diff options
author | Mike Jones <mjjones@us.ibm.com> | 2013-03-13 20:39:31 -0500 |
---|---|---|
committer | A. Patrick Williams III <iawillia@us.ibm.com> | 2013-04-15 15:42:50 -0500 |
commit | 54a7754855469231b10e644abaa5b3f367fcf00e (patch) | |
tree | b3439b41b90e9b6d315ad43cf3d463e64fc97612 /src | |
parent | 6e42444a52f2910a0a6f9a898c2ba4a9e8201a17 (diff) | |
download | talos-hostboot-54a7754855469231b10e644abaa5b3f367fcf00e.tar.gz talos-hostboot-54a7754855469231b10e644abaa5b3f367fcf00e.zip |
Extend Attribute Override/Sync to work on Targeting attributes
Change-Id: Icf8d84e741212f31c1065146ac1ea96c4c7d75c5
RTC: 51707
Reviewed-on: http://gfw160.austin.ibm.com:8080/gerrit/3548
Reviewed-by: A. Patrick Williams III <iawillia@us.ibm.com>
Tested-by: Jenkins Server
Diffstat (limited to 'src')
28 files changed, 3773 insertions, 3092 deletions
diff --git a/src/build/debug/Hostboot/HwpfAttrOverride.pm b/src/build/debug/Hostboot/HwpfAttrOverride.pm index ef595bcee..daff19f5b 100755 --- a/src/build/debug/Hostboot/HwpfAttrOverride.pm +++ b/src/build/debug/Hostboot/HwpfAttrOverride.pm @@ -1,26 +1,26 @@ #!/usr/bin/perl -# IBM_PROLOG_BEGIN_TAG -# This is an automatically generated prolog. +# IBM_PROLOG_BEGIN_TAG +# This is an automatically generated prolog. # -# $Source: src/build/debug/Hostboot/HwpfAttrOverride.pm $ +# $Source: src/build/debug/Hostboot/HwpfAttrOverride.pm $ # -# IBM CONFIDENTIAL +# IBM CONFIDENTIAL # -# COPYRIGHT International Business Machines Corp. 2012 +# COPYRIGHT International Business Machines Corp. 2012,2013 # -# p1 +# p1 # -# Object Code Only (OCO) source materials -# Licensed Internal Code Source Materials -# IBM HostBoot Licensed Internal Code +# Object Code Only (OCO) source materials +# Licensed Internal Code Source Materials +# IBM HostBoot Licensed Internal Code # -# The source code for this program is not published or other- -# wise divested of its trade secrets, irrespective of what has -# been deposited with the U.S. Copyright Office. +# 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. # -# Origin: 30 +# Origin: 30 # -# IBM_PROLOG_END_TAG +# IBM_PROLOG_END_TAG # # This perl module will be used in a standalone Hostboot environment @@ -52,18 +52,21 @@ use constant TARGET_TYPE_MCS_CHIPLET => 0x00000040; use constant TARGET_TYPE_XBUS_ENDPOINT => 0x00000080; use constant TARGET_TYPE_ABUS_ENDPOINT => 0x00000100; -# From fapiAttributeTank.H +# From attributeTank.H use constant ATTR_POS_NA => 0xffff; use constant ATTR_UNIT_POS_NA => 0xff; -use constant ATTR_ARRAYD_NA => 0xff; use constant ATTR_FLAG_CONST => 1; -# From fapiPlatAttrOverrideDirect.C +# From fapiPlatAttrOverrideSync.C +use constant MAX_DIRECT_OVERRIDE_ATTR_SIZE_BYTES => 64; +my $overrideHeaderSymbol = 'fapi::g_attrOverrideHeader'; my $overrideSymbol = 'fapi::g_attrOverride'; +my $overrideFapiTankSymbol = 'fapi::g_attrOverrideFapiTank'; # Expected filenames -my $attributeIdsFileName = 'fapiAttributeIds.txt'; -my $attributeEnumsFileName = 'fapiAttributeEnums.txt'; +my $fapiAttrInfoFileName = 'fapiAttrInfo.csv'; +my $fapiAttrEnumInfoFileName = 'fapiAttrEnumInfo.csv'; +my $targAttrInfoFileName = 'targAttrInfo.csv'; my $overrideFileName = 'OverrideAttrs.txt'; sub main @@ -76,389 +79,591 @@ sub main } #-------------------------------------------------------------------------- - # Check if the Attribute IDs/Enums and Attribute Overrides files exist + # Get the address of the Hostboot Attribute Override variables #-------------------------------------------------------------------------- - my $attributeIdsFile = ::getImgPath(); - $attributeIdsFile = $attributeIdsFile."$attributeIdsFileName"; - unless (-e $attributeIdsFile) + my $overrideHeaderSymAddr = (::findSymbolAddress("$overrideHeaderSymbol"))[0]; + + if (not defined $overrideHeaderSymAddr) + { + ::userDisplay "Cannot find Hostboot symbol '$overrideHeaderSymbol'\n"; + die; + } + + my $overrideHeaderAddr = Hostboot::_DebugFrameworkVMM::getPhysicalAddr( + $overrideHeaderSymAddr, $debug, 0); + + if ($overrideHeaderAddr eq Hostboot::_DebugFrameworkVMM::NotFound) { - die "Cannot find file $attributeIdsFile"; + ::userDisplay "Cannot translate '$overrideHeaderSymbol' to a phys addr\n"; + die; } - my $attributeEnumsFile = ::getImgPath(); - $attributeEnumsFile = $attributeEnumsFile."$attributeEnumsFileName"; - unless (-e $attributeEnumsFile) + #-------------------------------------------------------------------------- + my $overrideSymAddr = (::findSymbolAddress("$overrideSymbol"))[0]; + + if (not defined $overrideSymAddr) { - die "Cannot find file $attributeEnumsFile"; + ::userDisplay "Cannot find Hostboot symbol '$overrideSymbol'\n"; + die; + } + + my $overrideAddr = Hostboot::_DebugFrameworkVMM::getPhysicalAddr( + $overrideSymAddr, $debug, 0); + + if ($overrideAddr eq Hostboot::_DebugFrameworkVMM::NotFound) + { + ::userDisplay "Cannot translate '$overrideSymbol' to a phys addr\n"; + die; + } + + #-------------------------------------------------------------------------- + my $overrideFapiTankSymAddr = (::findSymbolAddress("$overrideFapiTankSymbol"))[0]; + + if (not defined $overrideFapiTankSymAddr) + { + ::userDisplay "Cannot find Hostboot symbol '$overrideFapiTankSymbol'\n"; + die; + } + + my $overrideFapiTankAddr = Hostboot::_DebugFrameworkVMM::getPhysicalAddr( + $overrideFapiTankSymAddr, $debug, 0); + + if ($overrideFapiTankAddr eq Hostboot::_DebugFrameworkVMM::NotFound) + { + ::userDisplay "Cannot translate '$overrideFapiTankSymbol' to a phys addr\n"; + die; + } + + #-------------------------------------------------------------------------- + # Check if the Attribute info and Override files exist + #-------------------------------------------------------------------------- + my $fapiAttrInfoFile = ::getImgPath(); + $fapiAttrInfoFile .= "$fapiAttrInfoFileName"; + unless (-e $fapiAttrInfoFile) + { + die "Cannot find file '$fapiAttrInfoFile'"; + } + + my $fapiAttrEnumInfoFile = ::getImgPath(); + $fapiAttrEnumInfoFile .= "$fapiAttrEnumInfoFileName"; + unless (-e $fapiAttrEnumInfoFile) + { + die "Cannot find file '$fapiAttrEnumInfoFile'"; + } + + my $targAttrInfoFile = ::getImgPath(); + $targAttrInfoFile .= "$targAttrInfoFileName"; + unless (-e $targAttrInfoFile) + { + die "Cannot find file '$targAttrInfoFile'"; } my $overrideFile = ::getImgPath(); $overrideFile = $overrideFile."$overrideFileName"; unless (-e $overrideFile) { - die "Cannot find file $overrideFile"; + die "Cannot find file '$overrideFile'"; + } + + #-------------------------------------------------------------------------- + # Process the FAPI Attribute Info file. Record the ATTR-ID-VAL and + # ATTR-TYPE in a hash indexed by ATTR-ID-STR. Note that for FAPI Attributes + # FAPI-ATTR-ID-STR and LAYER-ATTR-ID-STR will be identical + # + # Format: <FAPI-ATTR-ID-STR>,<LAYER-ATTR-ID-STR>,<ATTR-ID-VAL>,<ATTR-TYPE> + #-------------------------------------------------------------------------- + my %fapiAttrInfo; + + open(FAPIATTFILE, "< $fapiAttrInfoFile") or die + "Cannot open file '$fapiAttrInfoFile'"; + while (my $line = <FAPIATTFILE>) + { + chomp($line); + + # Skip comment lines + if (!($line =~ /^#/)) + { + if ($line =~ /(ATTR_\S+),ATTR_\S+,0x(\S+),(\S+)/) + { + $fapiAttrInfo{$1}->{idVal} = hex $2; + $fapiAttrInfo{$1}->{typeStr} = $3; + } + } } + close(FAPIATTFILE); #-------------------------------------------------------------------------- - # Process the Attribute ID file. Record the values of the Attribute IDs in - # a hash + # Process the TARG Attribute Info file. Record the ATTR-ID-VAL and + # ATTR-TYPE in a hash indexed by ATTR-ID-STR. Note that for TARG Attributes + # FAPI-ATTR-ID-STR and LAYER-ATTR-ID-STR may be different and if the + # TARG attribute does not map to a FAPI attribute then FAPI-ATTR-ID-STR + # will be NO-FAPI-ID + # + # Format: <FAPI-ATTR-ID-STR>,<LAYER-ATTR-ID-STR>,<ATTR-ID-VAL>,<ATTR-TYPE> #-------------------------------------------------------------------------- - my %attributeIdVals; + my %targAttrInfo; - open(IDFILE, "< $attributeIdsFile") or die "Cannot open file $attributeIdsFile"; - while (my $line = <IDFILE>) + open(TARGATTFILE, "< $targAttrInfoFile") or die + "Cannot open file '$targAttrInfoFile'"; + while (my $line = <TARGATTFILE>) { chomp($line); - if ($line =~ /(ATTR_\S+) 0x(\S+)/) + # Skip comment lines + if (!($line =~ /^#/)) { - # Found an attribute ID - $attributeIdVals{$1} = hex $2 + if ($line =~ /(\S+),(ATTR_\S+),(\S+),(\S+)/) + { + if ($1 ne "NO-FAPI-ID") + { + $targAttrInfo{$1}->{idVal} = $3; + $targAttrInfo{$1}->{typeStr} = $4; + } + + $targAttrInfo{$2}->{idVal} = $3; + $targAttrInfo{$2}->{typeStr} = $4; + } } } - close(IDFILE); + close(TARGATTFILE); #-------------------------------------------------------------------------- - # Process the Attribute ENUM file. Record the values of the Attribute ENUMs - # in a hash + # Process the FAPI Attribute Enum Info file. Record the values of the + # Attribute ENUMs in a hash #-------------------------------------------------------------------------- - my %attributeEnumVals; + my %fapiAttrEnumVals; - open(ENUMFILE, "< $attributeEnumsFile") or die "Cannot open file $attributeEnumsFile"; + open(ENUMFILE, "< $fapiAttrEnumInfoFile") or die + "Cannot open file '$fapiAttrEnumInfoFile'"; while (my $line = <ENUMFILE>) { # Note that enumerated values can end with 'ULL' if ($line =~ /(ATTR_\S+) = 0x([a-fA-F0-9]+)/) { # Found a hex attribute value enumeration - $attributeEnumVals{$1} = hex $2; + $fapiAttrEnumVals{$1} = hex $2; } elsif ($line =~ /(ATTR_\S+) = ([0-9]+)/) { # Found a decimal attribute value enumeration - $attributeEnumVals{$1} = $2; + $fapiAttrEnumVals{$1} = $2; } } close(ENUMFILE); - # Debug output - if ($debug) - { - foreach my $key (keys %attributeIdVals) - { - ::userDisplay "AttrIdVal: $key => $attributeIdVals{$key}\n"; - } - foreach my $key (keys %attributeEnumVals) - { - ::userDisplay "AttrEnumVal: $key => $attributeEnumVals{$key}\n"; - } - } - #-------------------------------------------------------------------------- - # Process the Attribute Overrides file. Record the information for each - # override in arrays + # Process the Attribute Overrides file #-------------------------------------------------------------------------- - my @attrIdString; - my @val; - my @attrId; - my @targetType; - my @pos; - my @unitPos; - my @flags; - my @arrayD1; - my @arrayD2; - my @arrayD3; - my @arrayD4; - + my $targLine = ""; my $numOverrides = 0; - my $curTargetType = TARGET_TYPE_SYSTEM; - my $curPos = ATTR_POS_NA; - my $curUnitPos = ATTR_UNIT_POS_NA; - - open(OVFILE, "< $overrideFile") or die "Cannot open file $overrideFile"; - - while (my $line = <OVFILE>) + my $attrString = ""; + my @attrLines; + + #-------------------------------------------------------------------------- + # Iterate over all lines in the Attribute Overrides file + #-------------------------------------------------------------------------- + open(OVFILE, "< $overrideFile") or die "Cannot open file '$overrideFile'"; + my $line = <OVFILE>; + while ($line ne "") { - chomp($line); - - if ($line =~ /^target = /) + #---------------------------------------------------------------------- + # Find all lines making up a single attribute override. There are + # multiple lines for a multi-dimensional attribute + #---------------------------------------------------------------------- + $attrString = ""; + @attrLines = (); + + while ($line ne "") { - # Found a target - my $p8pres = 0; + chomp($line); - # Figure out the target type - if ($line =~ /p8.ex/) + if ($line =~ /^target = /) { - $p8pres = 1; - $curTargetType = TARGET_TYPE_EX_CHIPLET; - } - elsif ($line =~ /centaur.mba/) - { - $curTargetType = TARGET_TYPE_MBA_CHIPLET; - } - elsif ($line =~ /p8.mcs/) - { - $p8pres = 1; - $curTargetType = TARGET_TYPE_MCS_CHIPLET; - } - elsif ($line =~ /p8.xbus/) - { - $p8pres = 1; - $curTargetType = TARGET_TYPE_XBUS_ENDPOINT; - } - elsif ($line =~ /p8.abus/) - { - $p8pres = 1; - $curTargetType = TARGET_TYPE_ABUS_ENDPOINT; - } - elsif ($line =~ /centaur/) - { - $curTargetType = TARGET_TYPE_MEMBUF_CHIP; - } - elsif ($line =~ /p8/) - { - $p8pres = 1; - $curTargetType = TARGET_TYPE_PROC_CHIP; + if ($attrString eq "") + { + # Not currently processing attribute lines, save the target + # line, it is for following attribute lines + $targLine = $line; + $line = <OVFILE>; + last; + } + else + { + # Currently processing attribute lines. Break out of the + # loop to process the current set and look at this target + # line in the next iteration + last; + } } - elsif ($line =~ /dimm/) + elsif ($line =~ /^(ATTR_\w+)/) { - $curTargetType = TARGET_TYPE_DIMM; + # Found an attribute override line + if ($attrString eq "") + { + # First override line for an attribute + $attrString = $1; + } + elsif ($attrString ne $1) + { + # Override line for a different attribute. Break out of the + # loop to process the current attribute override and look + # at this line in the next main loop + last; + } + + # Add the attribute override line to the set of lines to + # process for a single override and get the next line + push(@attrLines, $line); + $line = <OVFILE>; } else { - $curTargetType = TARGET_TYPE_SYSTEM; + # Not a target or attribute line, get the next line + $line = <OVFILE>; } + } # end of finding all lines making up a single attr override - # Figure out the position - if ($p8pres == 1) + if (scalar(@attrLines) > 0) + { + #------------------------------------------------------------------ + # Process the set of lines making up a single attribute override + #------------------------------------------------------------------ + my $attrIdStr = ""; + my $attrIdVal = 0; + my $fapiTank = 0; + my $elemSize = 0; + my $d1 = 1; # First dimension of the attribute + my $d2 = 1; + my $d3 = 1; + my $d4 = 1; + my $valSize = 0; + my $flags = 0; + + foreach my $attrLine(@attrLines) { - # Do not confuse 'p8' for position 8 - if ($line =~ /p8\S*:p(\d+)/) + my $td1 = 0; # First dimension of this line's element + my $td2 = 0; + my $td3 = 0; + my $td4 = 0; + my $val = 0; + + if ($attrIdStr eq "") { - $curPos = $1; + # This is the first line, figure out the attrIdStr + if ($attrLine =~ /^(ATTR_\w+)/) + { + $attrIdStr = $1; + } + else + { + ::userDisplay "Cannot find attr id str in '$attrLine'\n"; + die; + } + + # Use the data gathered from the AttrInfo files to figure out + # the attrIdVal, typeStr and tank Info + my $typeStr = ""; + + if (exists $targAttrInfo{$attrIdStr}) + { + $attrIdVal = $targAttrInfo{$attrIdStr}->{idVal}; + $typeStr = $targAttrInfo{$attrIdStr}->{typeStr}; + $fapiTank = 0; + } + elsif (exists $fapiAttrInfo{$attrIdStr}) + { + $attrIdVal = $fapiAttrInfo{$attrIdStr}->{idVal}; + $typeStr = $fapiAttrInfo{$attrIdStr}->{typeStr}; + $fapiTank = 1; + } + else + { + ::userDisplay "Cannot find '$attrIdStr' in attribute info files\n"; + die; + } + + # Figure out the attribute element size + if ($typeStr =~ /^u8/) + { + $elemSize = 1; + } + elsif ($typeStr =~ /^u16/) + { + $elemSize = 2; + } + elsif ($typeStr =~ /^u32/) + { + $elemSize = 4; + } + elsif ($typeStr =~ /^u64/) + { + $elemSize = 8; + } + else + { + ::userDisplay "Bad type string '$typeStr' in attribute info file\n"; + die; + } + + # Remove the attribute element type from typeStr + $typeStr =~ s/u\w+//; + + # Figure out the attribute array dimensions + if ($typeStr =~ /^\[(\d+)\]/) + { + $d1 = $1; + } + if ($typeStr =~ /^\[\d+\]\[(\d+)\]/) + { + $d2 = $1; + } + if ($typeStr =~ /^\[\d+\]\[\d+\]\[(\d+)\]/) + { + $d3 = $1; + } + if ($typeStr =~ /^\[\d+\]\[\d+\]\[\d+\]\[(\d+)\]/) + { + $d4 = $1; + } + + # Calculate the attribute value size + $valSize = $elemSize * $d1 * $d2 * $d3 * $d4; + + if ($valSize > MAX_DIRECT_OVERRIDE_ATTR_SIZE_BYTES) + { + ::userDisplay "Attribute size too big ($valSize bytes) to directly override\n"; + die; + } } - else + + # Figure out this element's dimensions + if ($attrLine =~ /^ATTR_\w+\[(\d+)\]/) { - $curPos = ATTR_POS_NA; + $td1 = $1; } - } - else - { - if ($line =~ /:p(\d+)/) + if ($attrLine =~ /^ATTR_\w+\[\d+\]\[(\d+)\]/) + { + $td2 = $1; + } + if ($attrLine =~ /^ATTR_\w+\[\d+\]\[\d+\]\[(\d+)\]/) + { + $td3 = $1; + } + if ($attrLine =~ /^ATTR_\w+\[\d+\]\[\d+\]\[\d+\]\[(\d+)\]/) { - $curPos = $1; + $td4 = $1; + } + + # Check for overflow + if (($td1 >= $d1) || ($td2 >= $d2) || ($td3 >= $d3) || + ($td4 >= $d4)) + { + ::userDisplay "Attribute '$attrLine' overflows its array\n"; + ::userDisplay "$td1:$d1:$td2:$d2:$td3:$d3:$td4:$d4\n"; + die; + } + + # Remove the Attribute ID and any dimensions from the line + $attrLine =~ s/^ATTR_\S+\s+//; + + # If the line includes a type field then remove it + $attrLine =~ s/^u8\S*\s+//; + $attrLine =~ s/^u16\S*\s+//; + $attrLine =~ s/^u32\S*\s+//; + $attrLine =~ s/^u64\S*\s+//; + + # Figure out the override value + if ($attrLine =~ /^([A-Za-z]+\S*)/) + { + # enumerator + my $enum = "$attrIdStr"."_$1"; + if (exists $fapiAttrEnumVals{$enum}) + { + $val = $fapiAttrEnumVals{$enum}; + } + else + { + ::userDisplay "Cannot find enum '$enum' in '$fapiAttrEnumInfoFile'\n"; + die; + } + } + elsif ($attrLine =~ /^0x([0-9A-Za-z]+)/) + { + # Hex value + $val = hex $1; + } + elsif ($attrLine =~ /^(\d+)/) + { + # Decimal Value + $val = $1; } else { - $curPos = ATTR_POS_NA; + ::userDisplay "Cannot find override value for '$attrIdStr'\n"; + die; } - } - # Figure out the unit position - if ($line =~ /:c(\d+)/) - { - $curUnitPos = $1; - } - else + # Figure out if it is a const override + if ($attrLine =~ /CONST\s*/) + { + $flags = ATTR_FLAG_CONST; + } + + # Write element to Hostboot memory + my $addr = $overrideAddr; + + my $elemNum = $td4 + ($td3*$d4) + ($td2*$d3*$d4) + + ($td1*$d2*$d3*$d4); + $addr += $elemNum * $elemSize; + + if ($elemSize == 1) + { + ::write8($addr, $val); + } + elsif ($elemSize == 2) + { + ::write16($addr, $val); + } + elsif ($elemSize == 4) + { + ::write32($addr, $val); + } + elsif ($elemSize == 8) + { + ::write64($addr, $val); + } + + } # end of processing all lines making up a single attr override + + #------------------------------------------------------------------ + # Figure out the Target type/pos/unitpos + #------------------------------------------------------------------ + my $targType = TARGET_TYPE_SYSTEM; + my $targPos = ATTR_POS_NA; + my $targUnitPos = ATTR_UNIT_POS_NA; + + # Figure out the target type + my $targ = $targLine; + + if ($targ =~ /p8.ex/) { - $curUnitPos = ATTR_UNIT_POS_NA; + $targType = TARGET_TYPE_EX_CHIPLET; + $targ =~ s/^.*p8.ex//; } - } - elsif ($line =~ /^(ATTR_\w+)/) - { - # Found an override - $attrIdString[$numOverrides] = $1; - $targetType[$numOverrides] = $curTargetType; - $pos[$numOverrides] = $curPos; - $unitPos[$numOverrides] = $curUnitPos; - - # Figure out the attribute ID - if (exists $attributeIdVals{$1}) + elsif ($targ =~ /centaur.mba/) { - $attrId[$numOverrides] = $attributeIdVals{$1}; + $targType = TARGET_TYPE_MBA_CHIPLET; + $targ =~ s/^.*centaur.mba//; } - else + elsif ($targ =~ /p8.mcs/) { - ::userDisplay "Cannot find ID $1 in $attributeIdsFile\n"; - die; + $targType = TARGET_TYPE_MCS_CHIPLET; + $targ =~ s/^.*p8.mcs//; } - - # Figure out the attribute array dimensions - if ($line =~ /^ATTR_\w+\[(\d)\]\[(\d)\]\[(\d)\]\[(\d)\] /) + elsif ($targ =~ /p8.xbus/) { - # 4D array override - $arrayD1[$numOverrides] = $1; - $arrayD2[$numOverrides] = $2; - $arrayD3[$numOverrides] = $3; - $arrayD4[$numOverrides] = $4; + $targType = TARGET_TYPE_XBUS_ENDPOINT; + $targ =~ s/^.*p8.xbus//; } - elsif ($line =~ /^ATTR_\w+\[(\d)\]\[(\d)\]\[(\d)\] /) + elsif ($targ =~ /p8.abus/) { - # 3D array override - $arrayD1[$numOverrides] = $1; - $arrayD2[$numOverrides] = $2; - $arrayD3[$numOverrides] = $3; - $arrayD4[$numOverrides] = ATTR_ARRAYD_NA; + $targType = TARGET_TYPE_ABUS_ENDPOINT; + $targ =~ s/^.*p8.abus//; } - elsif ($line =~ /^ATTR_\w+\[(\d)\]\[(\d)\] /) + elsif ($targ =~ /centaur/) { - # 2D array override - $arrayD1[$numOverrides] = $1; - $arrayD2[$numOverrides] = $2; - $arrayD3[$numOverrides] = ATTR_ARRAYD_NA; - $arrayD4[$numOverrides] = ATTR_ARRAYD_NA; + $targType = TARGET_TYPE_MEMBUF_CHIP; + $targ =~ s/^.*centaur//; } - elsif ($line =~ /^ATTR_\w+\[(\d)\] /) + elsif ($targ =~ /dimm/) { - # 1D array override - $arrayD1[$numOverrides] = $1; - $arrayD2[$numOverrides] = ATTR_ARRAYD_NA; - $arrayD3[$numOverrides] = ATTR_ARRAYD_NA; - $arrayD4[$numOverrides] = ATTR_ARRAYD_NA; + $targType = TARGET_TYPE_DIMM; + $targ =~ s/^.*dimm//; } - else + elsif ($targ =~ /p8/) { - # Non-array attribute - $arrayD1[$numOverrides] = ATTR_ARRAYD_NA; - $arrayD2[$numOverrides] = ATTR_ARRAYD_NA; - $arrayD3[$numOverrides] = ATTR_ARRAYD_NA; - $arrayD4[$numOverrides] = ATTR_ARRAYD_NA; + $targType = TARGET_TYPE_PROC_CHIP; + $targ =~ s/^.*p8//; } - # Figure out the override value - if ($line =~ /^ATTR_\S+\s+([A-Za-z]+\S*)/) - { - # enumerator - my $enum = "$attrIdString[$numOverrides]"."_$1"; - if (exists $attributeEnumVals{$enum}) - { - $val[$numOverrides] = $attributeEnumVals{$enum}; - } - else - { - ::userDisplay "Cannot find enum $enum in $attributeEnumsFile\n"; - die; - } - } - elsif ($line =~ /^ATTR_\S+\s+0x([0-9A-Za-z]+)/) - { - # Hex value - $val[$numOverrides] = hex $1; - } - elsif ($line =~ /^ATTR_\S+\s+(\d+)/) + # Figure out the position + if ($targ =~ /:p(\d+)/) { - # Decimal Value - $val[$numOverrides] = $1; + $targPos = $1; } else { - ::userDisplay "Cannot find override value for $attrIdString[$numOverrides]\n"; - die; + $targPos = ATTR_POS_NA; } - # Figure out if it is a const override - if ($line =~ /CONST\s*/) + # Figure out the unit position + if ($targ =~ /:c(\d+)/) { - $flags[$numOverrides] = ATTR_FLAG_CONST; + $targUnitPos = $1; } else { - $flags[$numOverrides] = 0; + $targUnitPos = ATTR_UNIT_POS_NA; } # Debug output if ($debug) { - ::userDisplay "OVERRIDE. Val: $val[$numOverrides]. "; - ::userDisplay "ID: $attrId[$numOverrides]. "; - ::userDisplay "TargType: $targetType[$numOverrides]. "; - ::userDisplay "Pos: $pos[$numOverrides].$unitPos[$numOverrides].\n"; - ::userDisplay " OFlags: $flags[$numOverrides]. "; - ::userDisplay "Dims: $arrayD1[$numOverrides]."; - ::userDisplay "$arrayD2[$numOverrides]."; - ::userDisplay "$arrayD3[$numOverrides]."; - ::userDisplay "$arrayD4[$numOverrides]\n"; + ::userDisplay "OVERRIDE. ID: $attrIdVal. "; + ::userDisplay "Targ: $targType.$targPos.$targUnitPos. "; + ::userDisplay "Flags: $flags\n"; } - $numOverrides++; - } - } - close(OVFILE); + #------------------------------------------------------------------ + # Write the overide to Hostboot memory + #------------------------------------------------------------------ + # From attributeTank.H + # struct AttributeHeader + # { + # uint32_t iv_attrId; // Attribute ID + # uint32_t iv_targetType; // Target Type attribute is for + # uint16_t iv_pos; // For chips/dimms the position + # // For chiplets the parent chip position + # uint8_t iv_unitPos; // For chiplets the position + # uint8_t iv_flags; // AttributeFlags enum value(s) + # uint32_t iv_valSize; // Size of the attribute value in bytes + # }; + my $addr = $overrideHeaderAddr; + ::write32($addr, $attrIdVal); + $addr += 4; + ::write32($addr, $targType); + $addr += 4; + ::write16($addr, $targPos); + $addr += 2; + ::write8($addr, $targUnitPos); + $addr += 1; + ::write8($addr, $flags); + $addr += 1; + ::write32($addr, $valSize); + + $addr = $overrideFapiTankAddr; + ::write8($addr, $fapiTank); + + #------------------------------------------------------------------ + # Tell Hostboot to apply the override + #------------------------------------------------------------------ + my $callFuncForce = 0; + my @callFuncParms; + Hostboot::CallFunc::execFunc("fapi::directOverride()", + $debug, $callFuncForce, \@callFuncParms); - #-------------------------------------------------------------------------- - # Get the address of the Hostboot Attribute Override variable - #-------------------------------------------------------------------------- - my $overrideSymAddr = (::findSymbolAddress("$overrideSymbol"))[0]; - - if (not defined $overrideSymAddr) - { - ::userDisplay "Cannot find Hostboot symbol $overrideSymbol\n"; - die; - } + if ($debug) + { + ::userDisplay "$attrIdStr sent\n"; + } - my $overrideAddr = - Hostboot::_DebugFrameworkVMM::getPhysicalAddr($overrideSymAddr, $debug, 0); + $numOverrides++; - if ($overrideAddr eq Hostboot::_DebugFrameworkVMM::NotFound) - { - ::userDisplay "Cannot translate $overrideSymbol to a physical address\n"; - die; - } + } # end of if there is an atribute override to process - # From fapiAttributeOverride.H - # struct AttributeOverride - # { - # uint64_t iv_val; // Large enough to hold the biggest attribute size - # uint32_t iv_attrId; // fapi::AttributeId enum value - # uint32_t iv_targetType; // fapi::TargetType enum value - # uint16_t iv_pos; // For chips/dimms the position - # // For chiplets the parent chip position - # uint8_t iv_unitPos; // For chiplets the position - # uint8_t iv_flags; // fapi::AttributeFlags enum value - # uint8_t iv_arrayD1; // Applies to element D1 in 1D or more array atts - # uint8_t iv_arrayD2; // Applies to element D2 in 2D or more array atts - # uint8_t iv_arrayD3; // Applies to element D3 in 3D or more array atts - # uint8_t iv_arrayD4; // Applies to element D4 in 4D array atts - # }; + } # end of iterating over all lines in an attr override file - #-------------------------------------------------------------------------- - # Send the overrides to Hostboot - #-------------------------------------------------------------------------- - for (my $i = 0; $i < $numOverrides; $i++) - { - # Write override to Hostboot - my $addr = $overrideAddr; - ::write64($addr, $val[$i]); - $addr += 8; - ::write32($addr, $attrId[$i]); - $addr += 4; - ::write32($addr, $targetType[$i]); - $addr += 4; - ::write16($addr, $pos[$i]); - $addr += 2; - ::write8($addr, $unitPos[$i]); - $addr++; - ::write8($addr, $flags[$i]); - $addr++; - ::write8($addr, $arrayD1[$i]); - $addr++; - ::write8($addr, $arrayD2[$i]); - $addr++; - ::write8($addr, $arrayD3[$i]); - $addr++; - ::write8($addr, $arrayD4[$i]); - - # Tell Hostboot to process the override - my $callFuncForce = 0; - my @callFuncParms; - Hostboot::CallFunc::execFunc("fapi::attrOverrideSync::directOverride()", - $debug, $callFuncForce, \@callFuncParms); - - if ($debug) - { - ::userDisplay "$attrIdString[$i] sent\n"; - } - } + close(OVFILE); ::userDisplay "All $numOverrides override(s) successfully sent to Hostboot\n"; } @@ -471,9 +676,11 @@ sub helpInfo options => { "debug" => ["More debug output."], }, - notes => ["Looks for three files in the image directory", - "$attributeIdsFileName: Contains attribute id values", - "$attributeEnumsFileName: Contains attribute enum values", + notes => ["Looks for four files in the image directory", + "$fapiAttrInfoFileName: Contains FAPI attribute info", + "$fapiAttrEnumInfoFileName: Contains FAPI attribute enum info", + "$targAttrInfoFileName: Contains TARG attribute info", "$overrideFileName: Contains the attribute overrides"] ); } + diff --git a/src/build/mkrules/dist.targets.mk b/src/build/mkrules/dist.targets.mk index 637b4764c..aef696d2c 100644 --- a/src/build/mkrules/dist.targets.mk +++ b/src/build/mkrules/dist.targets.mk @@ -61,8 +61,9 @@ COPY_FILES = \ img/dimmspd.dat:vpo \ img/procmvpd.dat:vpo \ img/cvpd.dat:vpo \ - obj/genfiles/fapiAttributeIds.txt:vpo \ - obj/genfiles/fapiAttributeEnums.txt:vpo \ + obj/genfiles/fapiAttrInfo.csv:vpo \ + obj/genfiles/fapiAttrEnumInfo.csv:vpo \ + obj/genfiles/targAttrInfo.csv:vpo \ src/build/hwpf/prcd_compile.tcl:tools \ src/usr/hwpf/hwp/initfiles/sample.initfile:tools \ $(foreach file, $(call ROOTPATH_WILDCARD,releaseNotes.html), $(file):fsp)\ @@ -153,8 +154,9 @@ simics.tar_CONTENTS = \ img/dimmspd.dat \ img/procmvpd.dat \ img/cvpd.dat \ - obj/genfiles/fapiAttributeIds.txt \ - obj/genfiles/fapiAttributeEnums.txt \ + obj/genfiles/fapiAttrInfo.csv \ + obj/genfiles/fapiAttrEnumInfo.csv \ + obj/genfiles/targAttrInfo.csv # # Contents for the fsp.tar. @@ -168,8 +170,9 @@ fsp.tar_CONTENTS = \ src/build/buildpnor/defaultPnorLayout.xml \ img/simics_MURANO_targeting.bin \ img/simics_VENICE_targeting.bin \ - obj/genfiles/fapiAttributeIds.txt \ - obj/genfiles/fapiAttributeEnums.txt \ + obj/genfiles/fapiAttrInfo.csv \ + obj/genfiles/fapiAttrEnumInfo.csv \ + obj/genfiles/targAttrInfo.csv \ $(addsuffix :targeting/,\ $(call ROOTPATH_WILDCARD_RECURSIVE,src/usr/targeting/common))\ $(addsuffix :targeting/,\ diff --git a/src/include/usr/hwpf/fapi/fapiAttributeService.H b/src/include/usr/hwpf/fapi/fapiAttributeService.H index 186a43222..3c6b0dff4 100644 --- a/src/include/usr/hwpf/fapi/fapiAttributeService.H +++ b/src/include/usr/hwpf/fapi/fapiAttributeService.H @@ -5,7 +5,7 @@ /* */ /* IBM CONFIDENTIAL */ /* */ -/* COPYRIGHT International Business Machines Corp. 2011,2012 */ +/* COPYRIGHT International Business Machines Corp. 2011,2013 */ /* */ /* p1 */ /* */ @@ -41,6 +41,7 @@ * ptr * mjjones 04/10/2012 Support for privileged atts * mjjones 06/07/2012 Add attr override support + * mjjones 03/13/2013 Move attr override code to plat */ #ifndef FAPIATTRIBUTESERVICE_H_ @@ -78,46 +79,23 @@ * The PRIVILEGED macros call a template function (compiler will optimize out) * that will cause a compile failure if the ID is not valid or VAL is not the * correct type. - * The GET macro calls the FAPI_PLAT_GET_ATTR_OVERRIDE PLAT macro to find if - * there is an attribute override value to return (platforms can set this to - * false if they do not support attribute override or if they handle it in - * the standard <ID>_GETMACRO path), if this returns false then the - * <ID>_GETMACRO PLAT macro is called to get the attribute, platforms must - * define a _GETMACRO for each attribute. - * - * The SET macro calls the FAPI_PLAT_ATTR_SET_ACTIONS PLAT macro to perform - * any necessary platform actions on an attribute set, this includes - * clearing any non-const attribute override and storing the attribute for - * synchronization (platforms can set this to NULL if they do not need to - * take any actions). It then calls the <ID>_SETMACRO PLAT macro to set the - * attribute, platforms must define a _SETMACRO for each attribute - * - * Note that a const attribute override is one that is always returned on a - * FAPI_ATTR_GET even if a subsequent FAPI_ATTR_SET is done. A non-const - * attribute override is one that is cleared when a FAPI_ATTR_SET is done */ #define FAPI_ATTR_GET(ID, PTARGET, VAL) \ (fapi::fapiFailIfPrivileged<fapi::ID##_Privileged>(), \ fapi::fapiCheckIdType<fapi::ID##_Type>(fapi::ID, VAL), \ - FAPI_PLAT_GET_ATTR_OVERRIDE(fapi::ID, PTARGET, VAL) ? \ - fapi::FAPI_RC_SUCCESS \ - : ID##_GETMACRO(ID, PTARGET, VAL)) + ID##_GETMACRO(ID, PTARGET, VAL)) #define FAPI_ATTR_SET(ID, PTARGET, VAL) \ (fapi::fapiFailIfPrivileged<fapi::ID##_Privileged>(), \ fapi::fapiCheckIdType<fapi::ID##_Type>(fapi::ID, VAL), \ - FAPI_PLAT_ATTR_SET_ACTIONS(fapi::ID, PTARGET, VAL), \ ID##_SETMACRO(ID, PTARGET, VAL)) #define FAPI_ATTR_GET_PRIVILEGED(ID, PTARGET, VAL) \ (fapi::fapiCheckIdType<fapi::ID##_Type>(fapi::ID, VAL), \ - FAPI_PLAT_GET_ATTR_OVERRIDE(fapi::ID, PTARGET, VAL) ? \ - fapi::FAPI_RC_SUCCESS \ - : ID##_GETMACRO(ID, PTARGET, VAL)) + ID##_GETMACRO(ID, PTARGET, VAL)) #define FAPI_ATTR_SET_PRIVILEGED(ID, PTARGET, VAL) \ (fapi::fapiCheckIdType<fapi::ID##_Type>(fapi::ID, VAL), \ - FAPI_PLAT_ATTR_SET_ACTIONS(fapi::ID, PTARGET, VAL), \ ID##_SETMACRO(ID, PTARGET, VAL)) namespace fapi diff --git a/src/include/usr/hwpf/fapi/fapiAttributeTank.H b/src/include/usr/hwpf/fapi/fapiAttributeTank.H deleted file mode 100644 index a353c5e3f..000000000 --- a/src/include/usr/hwpf/fapi/fapiAttributeTank.H +++ /dev/null @@ -1,723 +0,0 @@ -/* IBM_PROLOG_BEGIN_TAG */ -/* This is an automatically generated prolog. */ -/* */ -/* $Source: src/include/usr/hwpf/fapi/fapiAttributeTank.H $ */ -/* */ -/* IBM CONFIDENTIAL */ -/* */ -/* COPYRIGHT International Business Machines Corp. 2012 */ -/* */ -/* p1 */ -/* */ -/* Object Code Only (OCO) source materials */ -/* Licensed Internal Code Source Materials */ -/* IBM HostBoot Licensed Internal Code */ -/* */ -/* 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. */ -/* */ -/* Origin: 30 */ -/* */ -/* IBM_PROLOG_END_TAG */ -/** - * @file fapiAttributeTank.H - * - * @brief Defines the AttributeTank and Attribute classes. A platform can - * choose to use these classes to store attributes for Attribute - * Overriding and Synchronization - */ - -/* - * Change Log ****************************************************************** - * Flag Defect/Feature User Date Description - * ------ -------------- ---------- ----------- ---------------------------- - * mjjones 06/07/2012 Created - * mjjones 10/15/2012 Moved to general AttributeTank. - */ - -#ifndef FAPIATTRTANK_H_ -#define FAPIATTRTANK_H_ - -#include <stdint.h> -#include <list> -#include <vector> -#include <fapiAttributeIds.H> - -namespace fapi -{ - -class Target; // Forward Reference - -/** - * @enum AttributeFlags - * - * Enumeration of the possible attribute flags. This is a bitmap - */ -enum AttributeFlags -{ - ATTR_FLAG_CONST = 1, // Not cleared by clearNonConstAttribute - // Use-case is a constant Attribute Override -}; - -// Constants for various fields in Attribute -const uint16_t ATTR_POS_NA = 0xffff; // iv_pos not applicable -const uint8_t ATTR_UNIT_POS_NA = 0xff; // iv_unitPos not applicable -const uint8_t ATTR_ARRAYD_NA = 0xff; // iv_arrayDX not applicable - -/** - * @struct Attribute - * - * This structure defines a single attribute value. In the case of an array - * attribute, it is the value of one specific element - */ -struct Attribute -{ - /** - * @brief Constructor initializes default values - */ - Attribute(); - - uint64_t iv_val; // Value of attribute. - uint32_t iv_attrId; // fapi::AttributeId enum value - uint32_t iv_targetType; // fapi::TargetType enum value - uint16_t iv_pos; // For chips/dimms the position - // For chiplets the parent chip position - uint8_t iv_unitPos; // For chiplets the position - uint8_t iv_flags; // fapi::AttributeFlags enum value - uint8_t iv_arrayD1; // Applies to element D1 in 1D or more array atts - uint8_t iv_arrayD2; // Applies to element D2 in 2D or more array atts - uint8_t iv_arrayD3; // Applies to element D3 in 3D or more array atts - uint8_t iv_arrayD4; // Applies to element D4 in 4D array atts -}; - -/** - * @struct AttributeChunk - * - * This structure defines a chunk of memory containing Attributes. The max chunk - * size is chosen to be reasonable to send over a mailbox type interface - * between subsystems - */ -struct AttributeChunk -{ - static const size_t MAX_CHUNK_SIZE_BYTES = 4096; - static const size_t MAX_ATTRS_PER_CHUNK = - MAX_CHUNK_SIZE_BYTES / sizeof(Attribute); - - /** - * @brief Constructor initializes default values - */ - AttributeChunk(); - size_t iv_numAttributes; // Number of Attributes in chunk - uint8_t * iv_pAttributes; // Pointer to chunk of memory -}; - -/** - * @class AttributeTank - * - * This class can be used to store Attributes - */ -class AttributeTank -{ -public: - /** - * @brief Allocation types - */ - enum AllocType - { - ALLOC_TYPE_MALLOC = 1, - ALLOC_TYPE_NEW = 2, - }; - - /** - * @brief Default constructor - */ - AttributeTank(); - - /** - * @brief Destructor - */ - virtual ~AttributeTank(); - - /** - * @brief Clear all attributes - */ - virtual void clearAllAttributes(); - - /** - * @brief Clear any non-const attribute for a specified ID and Target - * - * Note that for array attributes, this clears all values of the array - * - * This is called on an OverrideAttributeTank to clear a non-const - * Attribute Override during FAPI_ATTR_SET - * - * @param[in] i_attrId Attribute ID - * @param[in] i_pTarget Pointer to Target (NULL if system) - */ - virtual void clearNonConstAttribute(const fapi::AttributeId i_attrId, - const fapi::Target * const i_pTarget); - - /** - * @brief Set an Attribute - * - * Note that for array attributes, this must be called repeatedly, to set - * the attribute value for each element of the array - * - * If the attribute already exists then it is replaced with the new one - * - * This is called on a SyncAttributeTank to save an Attribute for syncing - * during FAPI_ATTR_SET - * - * @param[in] i_attrId Attribute ID - * @param[in] i_pTarget Pointer to Target (NULL if system) - * @param[in] i_val Value - * @param[in] i_arrayD1 Array dimension 1 if applicable - * @param[in] i_arrayD2 Array dimension 2 if applicable - * @param[in] i_arrayD3 Array dimension 3 if applicable - * @param[in] i_arrayD4 Array dimension 4 if applicable - */ - virtual void setAttribute(const fapi::AttributeId i_attrId, - const fapi::Target * const i_pTarget, - const uint64_t i_val, - const uint8_t i_arrayD1 = ATTR_ARRAYD_NA, - const uint8_t i_arrayD2 = ATTR_ARRAYD_NA, - const uint8_t i_arrayD3 = ATTR_ARRAYD_NA, - const uint8_t i_arrayD4 = ATTR_ARRAYD_NA); - - /** - * @brief Set an attribute - * - * Note that for array attributes, this must be called repeatedly, to set - * the attribute value for each element of the array - * - * If the attribute already exists then it is replaced with the new one - * - * @param[in] i_attribute Reference to Attribute structure, this is copied - */ - virtual void setAttribute(const Attribute & i_attribute); - - /** - * @brief Get a copy of an Attribute - * - * Note that for array attributes, this must be called repeatedly, to query - * the attribute value for each element of the array - * - * This is called on an OverrideAttributeTank to query/get an Attribute - * Override during FAPI_ATTR_GET - * - * @param[in] i_attrId Attribute ID - * @param[in] i_pTarget Pointer to Target (NULL if system) - * @param[out] o_val Reference that is filled in with the attr value - * @param[in] i_arrayD1 Array dimension 1 if applicable - * @param[in] i_arrayD2 Array dimension 2 if applicable - * @param[in] i_arrayD3 Array dimension 3 if applicable - * @param[in] i_arrayD4 Array dimension 4 if applicable - * - * return true if attribute exists and a copy was returned. - */ - virtual bool getAttribute(const fapi::AttributeId i_attrId, - const fapi::Target * const i_pTarget, - uint64_t & o_val, - const uint8_t i_arrayD1 = ATTR_ARRAYD_NA, - const uint8_t i_arrayD2 = ATTR_ARRAYD_NA, - const uint8_t i_arrayD3 = ATTR_ARRAYD_NA, - const uint8_t i_arrayD4 = ATTR_ARRAYD_NA) const; - - /** - * @brief Get a copy of all Attributes into newly allocated memory chunks - * - * The use case is for getting the attributes to send across the FSP/ - * Hostboot mailbox. Mailbox frees the data memory using free on Hostboot - * and delete[] on FSP. - * - * @param[in] i_allocType Which allocation is used to allocated memory - * @param[out] o_attributes Reference to vector that AttributeChunk structs - * are added to. The caller must free (if MALLOC) - * or delete[] (if NEW) each chunk's memory - */ - virtual void getAllAttributes( - const AllocType i_allocType, - std::vector<AttributeChunk> & o_attributes) const; - - /** - * @brief Returns if any attributes exist in the tank - * - * This is only expected to be called by unit test - * - * return true if any attributes exist - */ - virtual bool attributesExist(); - -protected: - // The name of the Tank used in traces, a derived class can set - const char * iv_pName; - -private: - // Copy constructor and assignment operator disabled - AttributeTank(const AttributeTank & i_right); - AttributeTank & operator=(const AttributeTank & i_right); - - /** - * @brief Returns the Attribute::iv_targetType of the specified Target - * - * @param[in] i_pTarget Pointer to Target - * - * @return uint32_t target-type - */ - static uint32_t getTargetType(const fapi::Target * const i_pTarget); - - /** - * @brief Returns the Attribute::iv_pos of the specified Target - * - * @param[in] i_pTarget Pointer to Target - * - * @return uint16_t position - */ - static uint16_t getTargetPos(const fapi::Target * const i_pTarget); - - /** - * @brief Returns the Attribute::iv_unitPos of the specified Target - * - * @param[in] i_pTarget Pointer to Target - * - * @return uint8_t unit-position - */ - static uint8_t getTargetUnitPos(const fapi::Target * const i_pTarget); - - /** - * @brief Locks the AttributeTank object - * - * Pure virtual function that must be overridden by a concrete derived class - * and implemented by the platform - */ - virtual void platLock() const = 0 ; - - /** - * @brief Unlocks the AttributeTank object - * - * Pure virtual function that must be overridden by a concrete derived class - * and implemented by the platform - */ - virtual void platUnlock() const = 0; - - // The attributes - // Note: A possible performance boost could be to store the elements in a - // map, the key could be a sub-structure. - bool iv_attributesExist; - std::list<Attribute> iv_attributes; - typedef std::list<Attribute>::iterator AttributesItr_t; - typedef std::list<Attribute>::const_iterator AttributesCItr_t; - -}; - -/** - * @class OverrideAttributeTank - * - * This class can be used to store a set of attribute overrides. It is provided - * to allow a platform to create a singleton Tank for holding overrides - */ -class OverrideAttributeTank : public AttributeTank -{ -public: - OverrideAttributeTank(); - -private: - // Copy constructor and assignment operator disabled - OverrideAttributeTank(const OverrideAttributeTank & i_right); - OverrideAttributeTank & operator=(const OverrideAttributeTank & i_right); - - /** - * @brief Locks the OverrideAttributeTank object - * - * Must be implemented by the platform - */ - virtual void platLock() const; - - /** - * @brief Unlocks the AttributeTank object - * - * Must be implemented by the platform - */ - virtual void platUnlock() const; -}; - -/** - * @class SyncAttributeTank - * - * This class can be used to store a set of attributes to sync. It is provided - * to allow a platform to create a singleton Tank for holding attributes to sync - */ -class SyncAttributeTank : public AttributeTank -{ -public: - SyncAttributeTank(); - - /** - * @brief Set an Attribute - * - * This overrides the AttributeTank function, it checks if the platform - * has enabled synchronization before saving the attribute in the tank - * - * @param[in] i_attrId Attribute ID - * @param[in] i_pTarget Pointer to Target (NULL if system) - * @param[in] i_val Value - * @param[in] i_arrayD1 Array dimension 1 if applicable - * @param[in] i_arrayD2 Array dimension 2 if applicable - * @param[in] i_arrayD3 Array dimension 3 if applicable - * @param[in] i_arrayD4 Array dimension 4 if applicable - */ - virtual void setAttribute(const fapi::AttributeId i_attrId, - const fapi::Target * const i_pTarget, - const uint64_t i_val, - const uint8_t i_arrayD1 = ATTR_ARRAYD_NA, - const uint8_t i_arrayD2 = ATTR_ARRAYD_NA, - const uint8_t i_arrayD3 = ATTR_ARRAYD_NA, - const uint8_t i_arrayD4 = ATTR_ARRAYD_NA); - - /** - * @brief Set an attribute - * - * This overrides the AttributeTank function, it simply calls the base class - * function (needed because the other version of setAttribute was - * overridden) - * - * @param[in] i_attribute Reference to Attribute structure, this is copied - */ - virtual void setAttribute(const Attribute & i_attribute) - { - AttributeTank::setAttribute(i_attribute); - } - -private: - // Copy constructor and assignment operator disabled - SyncAttributeTank(const SyncAttributeTank & i_right); - SyncAttributeTank & operator=(const SyncAttributeTank & i_right); - - /** - * @brief Checks if the platform has enabled synchronization - * - * Must be implemented by the platform - */ - static bool platSyncEnabled(); - - /** - * @brief Locks the OverrideAttributeTank object - * - * Must be implemented by the platform - */ - virtual void platLock() const; - - /** - * @brief Unlocks the AttributeTank object - * - * Must be implemented by the platform - */ - virtual void platUnlock() const; -}; - -/** - * @brief This template function gets a 1D array attribute from an AttributeTank - * - * @param[in] i_attrId Attribute ID - * @param[in] i_pTarget Pointer to Target the attribute is for (NULL if system) - * @param[in] i_tank Reference to AttributeTank - * @param[out] o_1dArray Reference to 1D array where attribute will be copied to - * @return bool True if override was returned - */ -template <typename T, uint8_t SZ1> -bool getAttributeT(const fapi::AttributeId i_attrId, - const fapi::Target * const i_pTarget, - fapi::AttributeTank & i_tank, - T(&o_1dArray)[SZ1]) -{ - uint64_t l_val = 0; - - for (uint8_t d1 = 0; d1 < SZ1; d1++) - { - if (!(i_tank.getAttribute(i_attrId, i_pTarget, l_val, d1))) - { - // For array attributes, all elements must be overridden - return false; - } - else - { - // Standard conversion converts uint64_t to attribute type - o_1dArray[d1] = l_val; - } - } - - return true; -} - -/** - * @brief This template function gets a 2D array attribute from an AttributeTank - * - * @param[in] i_attrId Attribute ID - * @param[in] i_pTarget Pointer to Target the attribute is for (NULL if system) - * @param[in] i_tank Reference to AttributeTank - * @param[out] o_2dArray Reference to 2D array where attribute will be copied to - * @return bool True if override was returned - */ -template <typename T, uint8_t SZ1, uint8_t SZ2> -bool getAttributeT(const fapi::AttributeId i_attrId, - const fapi::Target * const i_pTarget, - fapi::AttributeTank & i_tank, - T(&o_2dArray)[SZ1][SZ2]) -{ - uint64_t l_val = 0; - - for (uint8_t d1 = 0; d1 < SZ1; d1++) - { - for (uint8_t d2 = 0; d2 < SZ2; d2++) - { - if (!(i_tank.getAttribute(i_attrId, i_pTarget, l_val, d1, d2))) - { - // For array attributes, all elements must be overridden - return false; - } - else - { - // Standard conversion converts uint64_t to attribute type - o_2dArray[d1][d2] = l_val; - } - } - } - - return true; -} - -/** - * @brief This template function gets a 3D array attribute from an AttributeTank - * - * @param[in] i_attrId Attribute ID - * @param[in] i_pTarget Pointer to Target the attribute is for (NULL if system) - * @param[in] i_tank Reference to AttributeTank - * @param[out] o_3dArray Reference to 3D array where attribute will be copied to - * @return bool True if override was returned - */ -template <typename T, uint8_t SZ1, uint8_t SZ2, uint8_t SZ3> -bool getAttributeT(const fapi::AttributeId i_attrId, - const fapi::Target * const i_pTarget, - fapi::AttributeTank & i_tank, - T(&o_3dArray)[SZ1][SZ2][SZ3]) -{ - uint64_t l_val = 0; - - for (uint8_t d1 = 0; d1 < SZ1; d1++) - { - for (uint8_t d2 = 0; d2 < SZ2; d2++) - { - for (uint8_t d3 = 0; d3 < SZ3; d3++) - { - if (!(i_tank.getAttribute(i_attrId, i_pTarget, l_val, d1, d2, - d3))) - { - // For array attributes, all elements must be overridden - return false; - } - else - { - // Standard conversion converts uint64_t to attribute type - o_3dArray[d1][d2][d3] = l_val; - } - } - } - } - - return true; -} - -/** - * @brief This template function gets a 4D array attribute from an AttributeTank - * - * @param[in] i_attrId Attribute ID - * @param[in] i_pTarget Pointer to Target the attribute is for (NULL if system) - * @param[in] i_tank Reference to AttributeTank - * @param[out] o_4dArray Reference to 4D array where attribute will be copied to - * @return bool True if override was returned - */ -template <typename T, uint8_t SZ1, uint8_t SZ2, uint8_t SZ3, uint8_t SZ4> -bool getAttributeT(const fapi::AttributeId i_attrId, - const fapi::Target * const i_pTarget, - fapi::AttributeTank & i_tank, - T(&o_4dArray)[SZ1][SZ2][SZ3][SZ4]) -{ - uint64_t l_val = 0; - - for (uint8_t d1 = 0; d1 < SZ1; d1++) - { - for (uint8_t d2 = 0; d2 < SZ2; d2++) - { - for (uint8_t d3 = 0; d3 < SZ3; d3++) - { - for (uint8_t d4 = 0; d4 < SZ4; d4++) - { - if (!(i_tank.getAttribute(i_attrId, i_pTarget, l_val, d1, d2, - d3, d4))) - { - // For array attributes, all elements must be overridden - return false; - } - else - { - // Standard conversion converts uint64_t to attribute - // type - o_4dArray[d1][d2][d3][d4] = l_val; - } - } - } - } - } - - return true; -} - -/** - * @brief This template function gets a non-array attribute from an - * AttributeTank - * - * @param[in] i_attrId Attribute ID - * @param[in] i_pTarget Pointer to Target the attribute is for (NULL if system) - * @param[in] i_tank Reference to AttributeTank - * @param[out] o_val Reference to variable where attribute will be copied to - * @return bool True if override was returned - */ -template <typename T> -bool getAttributeT(const fapi::AttributeId i_attrId, - const fapi::Target * const i_pTarget, - fapi::AttributeTank & i_tank, - T & o_val) -{ - uint64_t l_val = 0; - - if (!(i_tank.getAttribute(i_attrId, i_pTarget, l_val))) - { - return false; - } - - o_val = static_cast<T>(l_val); - return true; -} - -/** - * @brief This template function sets a 1D array attribute into an AttributeTank - * - * @param[in] i_attrId Attribute ID - * @param[in] i_pTarget Pointer to Target the attribute is for (NULL if system) - * @param[in] i_tank Reference to AttributeTank - * @param[in] i_1dArray Reference to 1D array containing attribute - */ -template <typename T, uint8_t SZ1> -void setAttributeT(const fapi::AttributeId i_attrId, - const fapi::Target * const i_pTarget, - fapi::AttributeTank & i_tank, - const T(&i_1dArray)[SZ1]) -{ - for (uint8_t d1 = 0; d1 < SZ1; d1++) - { - i_tank.setAttribute(i_attrId, i_pTarget, i_1dArray[d1], d1); - } -} - -/** - * @brief This template function sets a 2D array attribute into an AttributeTank - * - * @param[in] i_attrId Attribute ID - * @param[in] i_pTarget Pointer to Target the attribute is for (NULL if system) - * @param[in] i_tank Reference to AttributeTank - * @param[in] i_2dArray Reference to 2D array containing attribute - */ -template <typename T, uint8_t SZ1, uint8_t SZ2> -void setAttributeT(const fapi::AttributeId i_attrId, - const fapi::Target * const i_pTarget, - fapi::AttributeTank & i_tank, - const T(&i_2dArray)[SZ1][SZ2]) -{ - for (uint8_t d1 = 0; d1 < SZ1; d1++) - { - for (uint8_t d2 = 0; d2 < SZ2; d2++) - { - i_tank.setAttribute(i_attrId, i_pTarget, i_2dArray[d1][d2], d1, d2); - } - } -} - -/** - * @brief This template function sets a 3D array attribute into an AttributeTank - * - * @param[in] i_attrId Attribute ID - * @param[in] i_pTarget Pointer to Target the attribute is for (NULL if system) - * @param[in] i_tank Reference to AttributeTank - * @param[in] i_3dArray Reference to 3D array containing attribute - */ -template <typename T, uint8_t SZ1, uint8_t SZ2, uint8_t SZ3> -void setAttributeT(const fapi::AttributeId i_attrId, - const fapi::Target * const i_pTarget, - fapi::AttributeTank & i_tank, - const T(&i_3dArray)[SZ1][SZ2][SZ3]) -{ - for (uint8_t d1 = 0; d1 < SZ1; d1++) - { - for (uint8_t d2 = 0; d2 < SZ2; d2++) - { - for (uint8_t d3 = 0; d3 < SZ3; d3++) - { - i_tank.setAttribute(i_attrId, i_pTarget, i_3dArray[d1][d2][d3], - d1, d2, d3); - } - } - } -} - -/** - * @brief This template function sets a 4D array attribute into an AttributeTank - * - * @param[in] i_attrId Attribute ID - * @param[in] i_pTarget Pointer to Target the attribute is for (NULL if system) - * @param[in] i_tank Reference to AttributeTank - * @param[in] i_4dArray Reference to 4D array containing attribute - */ -template <typename T, uint8_t SZ1, uint8_t SZ2, uint8_t SZ3, uint8_t SZ4> -void setAttributeT(const fapi::AttributeId i_attrId, - const fapi::Target * const i_pTarget, - fapi::AttributeTank & i_tank, - const T(&i_4dArray)[SZ1][SZ2][SZ3][SZ4]) -{ - for (uint8_t d1 = 0; d1 < SZ1; d1++) - { - for (uint8_t d2 = 0; d2 < SZ2; d2++) - { - for (uint8_t d3 = 0; d3 < SZ3; d3++) - { - for (uint8_t d4 = 0; d4 < SZ4; d4++) - { - i_tank.setAttribute(i_attrId, i_pTarget, - i_4dArray[d1][d2][d3][d4], d1, d2, d3, d4); - } - } - } - } -} - -/** - * @brief This template function sets a non-array attribute into an - * AttributeTank - * - * @param[in] i_attrId Attribute ID - * @param[in] i_pTarget Pointer to Target the attribute is for (NULL if system) - * @param[in] i_tank Reference to AttributeTank - * @param[in] i_val Reference to variable containing attribute - */ -template <typename T> -void setAttributeT(const fapi::AttributeId i_attrId, - const fapi::Target * const i_pTarget, - fapi::AttributeTank & i_tank, - const T & i_val) -{ - i_tank.setAttribute(i_attrId, i_pTarget, i_val); -} - -} // namespace fapi - -#endif // FAPIATTRTANK_H_ diff --git a/src/include/usr/hwpf/plat/fapiPlatAttrOverrideSync.H b/src/include/usr/hwpf/plat/fapiPlatAttrOverrideSync.H index ab2a5ee3d..13b1ed96e 100755 --- a/src/include/usr/hwpf/plat/fapiPlatAttrOverrideSync.H +++ b/src/include/usr/hwpf/plat/fapiPlatAttrOverrideSync.H @@ -5,7 +5,7 @@ /* */ /* IBM CONFIDENTIAL */ /* */ -/* COPYRIGHT International Business Machines Corp. 2012 */ +/* COPYRIGHT International Business Machines Corp. 2012,2013 */ /* */ /* p1 */ /* */ @@ -21,9 +21,10 @@ /* */ /* IBM_PROLOG_END_TAG */ /** - * @file fapiPlatAttrOverrdieSync.H + * @file fapiPlatAttrOverrideSync.H * - * @brief Defines the functions for Attribute Override and Sync + * @brief Defines the AttrOverrideSync class that contains functions for + * Attribute Override and Sync */ #ifndef FAPIPLATATTROVERRIDESYNC_H_ @@ -33,7 +34,10 @@ // Includes //****************************************************************************** #include <stdint.h> -#include <hwpf/fapi/fapiAttributeTank.H> +#include <errl/errlentry.H> +#include <mbox/mboxif.H> +#include <fapiAttributeIds.H> +#include <targeting/common/attributeTank.H> //****************************************************************************** // Interface @@ -41,54 +45,203 @@ namespace fapi { -namespace attrOverrideSync -{ +// Forward references +class AttrOverrideSync; +class Target; /** - * @brief Monitors for incoming messages from the FSP. This must be called - * by a task specifically started to monitor for these messages + * @brief Return the AttrOverrideSync Singleton. Other modules must call this + * rather than using Singleton<> + * + * @return Reference to the AttrOverrideSync Singleton */ -void monitorForFspMessages(); +AttrOverrideSync & theAttrOverrideSync(); /** - * @brief Sends Attribute Overrides and Syncs to the FSP + * @class AttrOverrideSync * - * This is called at the end of an IStep. It: - * - Clears the FSP Attribute Overrides - * - Sends the Hostboot Attribute Overrides to the FSP - * - Sends the Hostboot Attribute Syncs to the FSP - */ -void sendAttrOverridesAndSyncsToFsp(); - -/** - * @brief This function returns the OverrideAttributeTank singleton. Other - * modules must call this rather than using Singleton<> + * This class contains the FAPI Attribute Override and Sync tanks. It provides + * functions to: + * - Monitor for incoming attribute override/sync messages from the FSP + * - Send attribute override/syncs to the FSP + * - Return any attribute override on an attribute get + * - Cancel any non-const attribute override and save the attribute in the sync + * tank on an attribute set */ -AttributeTank & theOverrideAttrTank(); +class AttrOverrideSync +{ +public: + /** + * @brief Allow a debug tool to directly access the override tank + */ + friend void directOverride(); -/** - * @brief This function returns the SyncAttributeTank singleton. Other - * modules must call this rather than using Singleton<> - */ -AttributeTank & theSyncAttrTank(); + /** + * @brief Maximum size of a direct attribute override + */ + static const size_t MAX_DIRECT_OVERRIDE_ATTR_SIZE_BYTES = 64; -} // namespace attrOverrideSync + /** + * @brief Attribute Override/Sync Mailbox Message Type Constants + * These must be kept in sync with FSP firmware + */ + enum MAILBOX_MSG_TYPE + { + MSG_SET_OVERRIDES = MBOX::FIRST_UNSECURE_MSG + 0x10, // FSP<->Hb + MSG_CLEAR_ALL_OVERRIDES = MBOX::FIRST_UNSECURE_MSG + 0x11, // FSP<->Hb + MSG_SET_SYNC_ATTS = MBOX::FIRST_UNSECURE_MSG + 0x12, // FSP<--Hb + }; -} // namespace fapi + /** + * @brief Default constructor + */ + AttrOverrideSync(); -/** - * @brief Macro that is called on a FAPI_ATTR_GET that returns any Attribute - * Override - */ -#define FAPI_PLAT_GET_ATTR_OVERRIDE(ID, PTARGET, VAL) \ - fapi::getAttributeT(ID, PTARGET, fapi::attrOverrideSync::theOverrideAttrTank(), VAL) + /** + * @brief Destructor + */ + ~AttrOverrideSync(); -/** - * @brief Macro that is called on a FAPI_ATTR_SET that clears any non-const - * Attribute Override and saves the Attribute to Sync - */ -#define FAPI_PLAT_ATTR_SET_ACTIONS(ID, PTARGET, VAL) \ - fapi::attrOverrideSync::theOverrideAttrTank().clearNonConstAttribute(ID, PTARGET), \ - fapi::setAttributeT(ID, PTARGET, fapi::attrOverrideSync::theSyncAttrTank(), VAL) + /** + * @brief Monitors for incoming attribute override messages from the FSP. + * This function never returns and must be called by a task + * specifically started to monitor for these messages + */ + void monitorForFspMessages(); + + /** + * @brief Sends Attribute Overrides and Syncs to the FSP + * + * This is called at the end of an IStep. For both FAPI/TARG tanks it: + * - Clears the FSP Attribute Overrides + * - Sends the Hostboot Attribute Overrides to the FSP + * - Sends the Hostboot Attribute Syncs to the FSP + */ + void sendAttrOverridesAndSyncsToFsp(); + + /** + * @brief This function gets any Attribute Override on an attribute get + * + * This is called for those FAPI Attributes that do not map to Targeting + * attributes - their overrides live in the FAPI Attribute tanks. + * + * @param[in] i_attrId FAPI Attribute ID + * @param[in] i_pTarget Pointer to FAPI Target + * @param[in] o_pVal Pointer to attribute value + * + * @return true if an override exists and was written to o_pVal + */ + bool getAttrOverride(const fapi::AttributeId i_attrId, + const fapi::Target * const i_pTarget, + void * o_pVal) const; + + /** + * @brief This function gets any Attribute Override on an attribute get + * + * This is a wrapper that calls getAttrOverride on the AttrOverrideSync + * singleton, it should be called by external modules to avoid the + * performance penalty of calling theAttrOverrideSync() then getAttrOverride + * + * @param[in] i_attrId FAPI Attribute ID + * @param[in] i_pTarget Pointer to FAPI Target + * @param[in] o_pVal Pointer to attribute value + * + * @return true if an override exists and was written to o_pVal + */ + static bool getAttrOverrideFunc(const fapi::AttributeId i_attrId, + const fapi::Target * const i_pTarget, + void * o_pVal); + + /** + * @brief This function performs the actions required on an attribute set + * + * This is called for those FAPI Attributes that do not map to Targeting + * attributes - their overrides/syncs live in the FAPI Attribute tanks. + * + * - Any non-const attribute override is cleared + * - The attribute is saved to be synced to Cronus (if Cronus Sync enabled) + * + * @param[in] i_attrId FAPI Attribute ID + * @param[in] i_pTarget Pointer to FAPI Target + * @param[in] i_size Size of attribute value + * @param[in] i_pVal Pointer to attribute value + */ + void setAttrActions(const fapi::AttributeId i_attrId, + const fapi::Target * const i_pTarget, + const uint32_t i_size, + const void * i_pVal); + + /** + * @brief This function performs the actions required on an attribute set + * + * This is a wrapper that calls setAttrActions on the AttrOverrideSync + * singleton, it should be called by external modules to avoid the + * performance penalty of calling theAttrOverrideSync() then setAttrActions + * + * @param[in] i_attrId FAPI Attribute ID + * @param[in] i_pTarget Pointer to FAPI Target + * @param[in] i_size Size of attribute value + * @param[in] i_pVal Pointer to attribute value + */ + static void setAttrActionsFunc(const fapi::AttributeId i_attrId, + const fapi::Target * const i_pTarget, + const uint32_t i_size, + const void * i_pVal); +private: + + /** + * @brief Utility function that sends attributes to the FSP + * + * This function frees the allocated memory in the input vector of chunks + * and empties the vector + * + * @param[in] i_msgType Message type (ID) to send + * @param[in] i_tankLayer Tank Layer to send attribute to + * @param[io] io_attributes Attributes to send. + * + * @return error log handle + */ + static errlHndl_t sendAttrsToFsp( + const MAILBOX_MSG_TYPE i_msgType, + const TARGETING::AttributeTank::TankLayer i_tankLayer, + std::vector<TARGETING::AttributeTank::AttributeSerializedChunk> & + io_attributes); + + /** + * @brief Utility function that gets the target type of a FAPI Target as + * used in an attribute tank + * + * @param[in] i_pTarget Pointer to FAPI Target (NULL = system) + * + * @return Target Type + */ + static uint32_t getTargetType(const fapi::Target * const i_pTarget); + + /** + * @brief Utility function that gets the target position of a FAPI Target + * as used in an attribute tank + * + * @param[in] i_pTarget Pointer to FAPI Target (NULL = system) + * + * @return Target Position + */ + static uint16_t getTargetPos(const fapi::Target * const i_pTarget); + + /** + * @brief Utility function that gets the target unit position of a FAPI + * Target as used in an attribute tank + * + * @param[in] i_pTarget Pointer to FAPI Target (NULL = system) + * + * @return Target Unit Position + */ + static uint8_t getTargetUnitPos(const fapi::Target * const i_pTarget); + + // The FAPI Attribute Tanks + TARGETING::AttributeTank iv_overrideTank; + TARGETING::AttributeTank iv_syncTank; +}; + +} // namespace fapi #endif // FAPIPLATATTROVERRIDESYNC_H_ diff --git a/src/include/usr/hwpf/plat/fapiPlatAttributeService.H b/src/include/usr/hwpf/plat/fapiPlatAttributeService.H index a0f8723a7..f9834bddd 100644 --- a/src/include/usr/hwpf/plat/fapiPlatAttributeService.H +++ b/src/include/usr/hwpf/plat/fapiPlatAttributeService.H @@ -52,7 +52,6 @@ #include <fapiplatattrmacros.H> #include <hwpf/fapi/fapiReturnCode.H> #include <hwpf/fapi/fapiTarget.H> -#include <hwpf/fapi/fapiAttributeTank.H> #include <hwpf/plat/fapiPlatAttrOverrideSync.H> #include <vpd/spdenums.H> #include <dimmConsts.H> @@ -446,114 +445,167 @@ fapi::ReturnCode fapiPlatGetProcPcieBarSize ( // MACROs to route each ATTR_SPD access to the Hostboot SPD function //------------------------------------------------------------------------------ #define ATTR_SPD_DRAM_DEVICE_TYPE_GETMACRO(ID, PTARGET, VAL) \ + fapi::AttrOverrideSync::getAttrOverrideFunc(fapi::ID, PTARGET, &VAL) ? fapi::FAPI_RC_SUCCESS : \ fapi::platAttrSvc::fapiPlatGetSpdAttr( PTARGET, SPD::BASIC_MEMORY_TYPE, &(VAL), sizeof(VAL) ) #define ATTR_SPD_MODULE_TYPE_GETMACRO(ID, PTARGET, VAL) \ + fapi::AttrOverrideSync::getAttrOverrideFunc(fapi::ID, PTARGET, &VAL) ? fapi::FAPI_RC_SUCCESS : \ fapi::platAttrSvc::fapiPlatGetSpdAttr( PTARGET, SPD::MODULE_TYPE, &(VAL), sizeof(VAL) ) #define ATTR_SPD_SDRAM_BANKS_GETMACRO(ID, PTARGET, VAL) \ + fapi::AttrOverrideSync::getAttrOverrideFunc(fapi::ID, PTARGET, &VAL) ? fapi::FAPI_RC_SUCCESS : \ fapi::platAttrSvc::fapiPlatGetSpdAttr( PTARGET, SPD::BANK_ADDRESS_BITS, &(VAL), sizeof(VAL) ) #define ATTR_SPD_SDRAM_DENSITY_GETMACRO(ID, PTARGET, VAL) \ + fapi::AttrOverrideSync::getAttrOverrideFunc(fapi::ID, PTARGET, &VAL) ? fapi::FAPI_RC_SUCCESS : \ fapi::platAttrSvc::fapiPlatGetSpdAttr( PTARGET, SPD::DENSITY, &(VAL), sizeof(VAL) ) #define ATTR_SPD_SDRAM_ROWS_GETMACRO(ID, PTARGET, VAL) \ + fapi::AttrOverrideSync::getAttrOverrideFunc(fapi::ID, PTARGET, &VAL) ? fapi::FAPI_RC_SUCCESS : \ fapi::platAttrSvc::fapiPlatGetSpdAttr( PTARGET, SPD::ROW_ADDRESS, &(VAL), sizeof(VAL) ) #define ATTR_SPD_SDRAM_COLUMNS_GETMACRO(ID, PTARGET, VAL) \ + fapi::AttrOverrideSync::getAttrOverrideFunc(fapi::ID, PTARGET, &VAL) ? fapi::FAPI_RC_SUCCESS : \ fapi::platAttrSvc::fapiPlatGetSpdAttr( PTARGET, SPD::COL_ADDRESS, &(VAL), sizeof(VAL) ) #define ATTR_SPD_MODULE_NOMINAL_VOLTAGE_GETMACRO(ID, PTARGET, VAL) \ + fapi::AttrOverrideSync::getAttrOverrideFunc(fapi::ID, PTARGET, &VAL) ? fapi::FAPI_RC_SUCCESS : \ fapi::platAttrSvc::fapiPlatGetSpdAttr( PTARGET, SPD::MODULE_NOMINAL_VOLTAGE, &(VAL), sizeof(VAL) ) #define ATTR_SPD_NUM_RANKS_GETMACRO(ID, PTARGET, VAL) \ + fapi::AttrOverrideSync::getAttrOverrideFunc(fapi::ID, PTARGET, &VAL) ? fapi::FAPI_RC_SUCCESS : \ fapi::platAttrSvc::fapiPlatGetSpdAttr( PTARGET, SPD::MODULE_RANKS, &(VAL), sizeof(VAL) ) #define ATTR_SPD_DRAM_WIDTH_GETMACRO(ID, PTARGET, VAL) \ + fapi::AttrOverrideSync::getAttrOverrideFunc(fapi::ID, PTARGET, &VAL) ? fapi::FAPI_RC_SUCCESS : \ fapi::platAttrSvc::fapiPlatGetSpdAttr( PTARGET, SPD::MODULE_DRAM_WIDTH, &(VAL), sizeof(VAL) ) #define ATTR_SPD_MODULE_MEMORY_BUS_WIDTH_GETMACRO(ID, PTARGET, VAL) \ + fapi::AttrOverrideSync::getAttrOverrideFunc(fapi::ID, PTARGET, &VAL) ? fapi::FAPI_RC_SUCCESS : \ fapi::platAttrSvc::fapiPlatGetSpdAttr( PTARGET, SPD::MODULE_MEMORY_BUS_WIDTH, &(VAL), sizeof(VAL) ) #define ATTR_SPD_FTB_DIVIDEND_GETMACRO(ID, PTARGET, VAL) \ + fapi::AttrOverrideSync::getAttrOverrideFunc(fapi::ID, PTARGET, &VAL) ? fapi::FAPI_RC_SUCCESS : \ fapi::platAttrSvc::fapiPlatGetSpdAttr( PTARGET, SPD::FTB_DIVIDEND, &(VAL), sizeof(VAL) ) #define ATTR_SPD_FTB_DIVISOR_GETMACRO(ID, PTARGET, VAL) \ + fapi::AttrOverrideSync::getAttrOverrideFunc(fapi::ID, PTARGET, &VAL) ? fapi::FAPI_RC_SUCCESS : \ fapi::platAttrSvc::fapiPlatGetSpdAttr( PTARGET, SPD::FTB_DIVISOR, &(VAL), sizeof(VAL) ) #define ATTR_SPD_MTB_DIVIDEND_GETMACRO(ID, PTARGET, VAL) \ + fapi::AttrOverrideSync::getAttrOverrideFunc(fapi::ID, PTARGET, &VAL) ? fapi::FAPI_RC_SUCCESS : \ fapi::platAttrSvc::fapiPlatGetSpdAttr( PTARGET, SPD::MTB_DIVIDEND, &(VAL), sizeof(VAL) ) #define ATTR_SPD_MTB_DIVISOR_GETMACRO(ID, PTARGET, VAL) \ + fapi::AttrOverrideSync::getAttrOverrideFunc(fapi::ID, PTARGET, &VAL) ? fapi::FAPI_RC_SUCCESS : \ fapi::platAttrSvc::fapiPlatGetSpdAttr( PTARGET, SPD::MTB_DIVISOR, &(VAL), sizeof(VAL) ) #define ATTR_SPD_TCKMIN_GETMACRO(ID, PTARGET, VAL) \ + fapi::AttrOverrideSync::getAttrOverrideFunc(fapi::ID, PTARGET, &VAL) ? fapi::FAPI_RC_SUCCESS : \ fapi::platAttrSvc::fapiPlatGetSpdAttr( PTARGET, SPD::TCK_MIN, &(VAL), sizeof(VAL) ) #define ATTR_SPD_CAS_LATENCIES_SUPPORTED_GETMACRO(ID, PTARGET, VAL) \ + fapi::AttrOverrideSync::getAttrOverrideFunc(fapi::ID, PTARGET, &VAL) ? fapi::FAPI_RC_SUCCESS : \ fapi::platAttrSvc::fapiPlatGetSpdAttr( PTARGET, SPD::CAS_LATENCIES_SUPPORTED, &(VAL), sizeof(VAL) ) #define ATTR_SPD_TAAMIN_GETMACRO(ID, PTARGET, VAL) \ + fapi::AttrOverrideSync::getAttrOverrideFunc(fapi::ID, PTARGET, &VAL) ? fapi::FAPI_RC_SUCCESS : \ fapi::platAttrSvc::fapiPlatGetSpdAttr( PTARGET, SPD::MIN_CAS_LATENCY, &(VAL), sizeof(VAL) ) #define ATTR_SPD_TWRMIN_GETMACRO(ID, PTARGET, VAL) \ + fapi::AttrOverrideSync::getAttrOverrideFunc(fapi::ID, PTARGET, &VAL) ? fapi::FAPI_RC_SUCCESS : \ fapi::platAttrSvc::fapiPlatGetSpdAttr( PTARGET, SPD::TWR_MIN, &(VAL), sizeof(VAL) ) #define ATTR_SPD_TRCDMIN_GETMACRO(ID, PTARGET, VAL) \ + fapi::AttrOverrideSync::getAttrOverrideFunc(fapi::ID, PTARGET, &VAL) ? fapi::FAPI_RC_SUCCESS : \ fapi::platAttrSvc::fapiPlatGetSpdAttr( PTARGET, SPD::TRCD_MIN, &(VAL), sizeof(VAL) ) #define ATTR_SPD_TRRDMIN_GETMACRO(ID, PTARGET, VAL) \ + fapi::AttrOverrideSync::getAttrOverrideFunc(fapi::ID, PTARGET, &VAL) ? fapi::FAPI_RC_SUCCESS : \ fapi::platAttrSvc::fapiPlatGetSpdAttr( PTARGET, SPD::TRRD_MIN, &(VAL), sizeof(VAL) ) #define ATTR_SPD_TRPMIN_GETMACRO(ID, PTARGET, VAL) \ + fapi::AttrOverrideSync::getAttrOverrideFunc(fapi::ID, PTARGET, &VAL) ? fapi::FAPI_RC_SUCCESS : \ fapi::platAttrSvc::fapiPlatGetSpdAttr( PTARGET, SPD::TRP_MIN, &(VAL), sizeof(VAL) ) #define ATTR_SPD_TRASMIN_GETMACRO(ID, PTARGET, VAL) \ + fapi::AttrOverrideSync::getAttrOverrideFunc(fapi::ID, PTARGET, &VAL) ? fapi::FAPI_RC_SUCCESS : \ fapi::platAttrSvc::fapiPlatGetSpdAttr( PTARGET, SPD::TRAS_MIN, &(VAL), sizeof(VAL) ) #define ATTR_SPD_TRCMIN_GETMACRO(ID, PTARGET, VAL) \ + fapi::AttrOverrideSync::getAttrOverrideFunc(fapi::ID, PTARGET, &VAL) ? fapi::FAPI_RC_SUCCESS : \ fapi::platAttrSvc::fapiPlatGetSpdAttr( PTARGET, SPD::TRC_MIN, &(VAL), sizeof(VAL) ) #define ATTR_SPD_TRFCMIN_GETMACRO(ID, PTARGET, VAL) \ + fapi::AttrOverrideSync::getAttrOverrideFunc(fapi::ID, PTARGET, &VAL) ? fapi::FAPI_RC_SUCCESS : \ fapi::platAttrSvc::fapiPlatGetSpdAttr( PTARGET, SPD::TRFC_MIN, &(VAL), sizeof(VAL) ) #define ATTR_SPD_TWTRMIN_GETMACRO(ID, PTARGET, VAL) \ + fapi::AttrOverrideSync::getAttrOverrideFunc(fapi::ID, PTARGET, &VAL) ? fapi::FAPI_RC_SUCCESS : \ fapi::platAttrSvc::fapiPlatGetSpdAttr( PTARGET, SPD::TWTR_MIN, &(VAL), sizeof(VAL) ) #define ATTR_SPD_TRTPMIN_GETMACRO(ID, PTARGET, VAL) \ + fapi::AttrOverrideSync::getAttrOverrideFunc(fapi::ID, PTARGET, &VAL) ? fapi::FAPI_RC_SUCCESS : \ fapi::platAttrSvc::fapiPlatGetSpdAttr( PTARGET, SPD::TRTP_MIN, &(VAL), sizeof(VAL) ) #define ATTR_SPD_TFAWMIN_GETMACRO(ID, PTARGET, VAL) \ + fapi::AttrOverrideSync::getAttrOverrideFunc(fapi::ID, PTARGET, &VAL) ? fapi::FAPI_RC_SUCCESS : \ fapi::platAttrSvc::fapiPlatGetSpdAttr( PTARGET, SPD::TFAW_MIN, &(VAL), sizeof(VAL) ) #define ATTR_SPD_SDRAM_OPTIONAL_FEATURES_GETMACRO(ID, PTARGET, VAL) \ + fapi::AttrOverrideSync::getAttrOverrideFunc(fapi::ID, PTARGET, &VAL) ? fapi::FAPI_RC_SUCCESS : \ fapi::platAttrSvc::fapiPlatGetSpdAttr( PTARGET, SPD::SPD_SDRAM_OPTIONAL_FEATURES, &(VAL), sizeof(VAL) ) #define ATTR_SPD_SDRAM_THERMAL_AND_REFRESH_OPTIONS_GETMACRO(ID, PTARGET, VAL ) \ + fapi::AttrOverrideSync::getAttrOverrideFunc(fapi::ID, PTARGET, &VAL) ? fapi::FAPI_RC_SUCCESS : \ fapi::platAttrSvc::fapiPlatGetSpdAttr( PTARGET, SPD::SPD_SDRAM_THERMAL_REFRESH_OPTIONS, &(VAL), sizeof(VAL) ) #define ATTR_SPD_MODULE_THERMAL_SENSOR_GETMACRO(ID, PTARGET, VAL) \ + fapi::AttrOverrideSync::getAttrOverrideFunc(fapi::ID, PTARGET, &VAL) ? fapi::FAPI_RC_SUCCESS : \ fapi::platAttrSvc::fapiPlatGetSpdAttr( PTARGET, SPD::SPD_MODULE_THERMAL_SENSOR, &(VAL), sizeof(VAL) ) #define ATTR_SPD_SDRAM_DEVICE_TYPE_GETMACRO(ID, PTARGET, VAL) \ + fapi::AttrOverrideSync::getAttrOverrideFunc(fapi::ID, PTARGET, &VAL) ? fapi::FAPI_RC_SUCCESS : \ fapi::platAttrSvc::fapiPlatGetSpdAttr( PTARGET, SPD::SDRAM_DEVICE_TYPE, &(VAL), sizeof(VAL) ) #define ATTR_SPD_SDRAM_DEVICE_TYPE_SIGNAL_LOADING_GETMACRO(ID, PTARGET, VAL) \ + fapi::AttrOverrideSync::getAttrOverrideFunc(fapi::ID, PTARGET, &VAL) ? fapi::FAPI_RC_SUCCESS : \ fapi::platAttrSvc::fapiPlatGetSpdAttr( PTARGET, SPD::SDRAM_DEVICE_TYPE_SIGNAL_LOADING, &(VAL), sizeof(VAL) ) #define ATTR_SPD_CUSTOM_GETMACRO(ID, PTARGET, VAL) \ + fapi::AttrOverrideSync::getAttrOverrideFunc(fapi::ID, PTARGET, &VAL) ? fapi::FAPI_RC_SUCCESS : \ fapi::platAttrSvc::fapiPlatGetSpdAttr( PTARGET, SPD::CUSTOM, &(VAL), sizeof(VAL) ) #define ATTR_SPD_SDRAM_DIE_COUNT_GETMACRO(ID, PTARGET, VAL) \ + fapi::AttrOverrideSync::getAttrOverrideFunc(fapi::ID, PTARGET, &VAL) ? fapi::FAPI_RC_SUCCESS : \ fapi::platAttrSvc::fapiPlatGetSpdAttr( PTARGET, SPD::SDRAM_DIE_COUNT, &(VAL), sizeof(VAL) ) #define ATTR_SPD_FINE_OFFSET_TCKMIN_GETMACRO(ID, PTARGET, VAL) \ + fapi::AttrOverrideSync::getAttrOverrideFunc(fapi::ID, PTARGET, &VAL) ? fapi::FAPI_RC_SUCCESS : \ fapi::platAttrSvc::fapiPlatGetSpdAttr( PTARGET, SPD::TCKMIN_FINE_OFFSET, &(VAL), sizeof(VAL) ) #define ATTR_SPD_FINE_OFFSET_TAAMIN_GETMACRO(ID, PTARGET, VAL) \ + fapi::AttrOverrideSync::getAttrOverrideFunc(fapi::ID, PTARGET, &VAL) ? fapi::FAPI_RC_SUCCESS : \ fapi::platAttrSvc::fapiPlatGetSpdAttr( PTARGET, SPD::TAAMIN_FINE_OFFSET, &(VAL), sizeof(VAL) ) #define ATTR_SPD_FINE_OFFSET_TRCDMIN_GETMACRO(ID, PTARGET, VAL) \ + fapi::AttrOverrideSync::getAttrOverrideFunc(fapi::ID, PTARGET, &VAL) ? fapi::FAPI_RC_SUCCESS : \ fapi::platAttrSvc::fapiPlatGetSpdAttr( PTARGET, SPD::TRCDMIN_FINE_OFFSET, &(VAL), sizeof(VAL) ) #define ATTR_SPD_FINE_OFFSET_TRPMIN_GETMACRO(ID, PTARGET, VAL) \ + fapi::AttrOverrideSync::getAttrOverrideFunc(fapi::ID, PTARGET, &VAL) ? fapi::FAPI_RC_SUCCESS : \ fapi::platAttrSvc::fapiPlatGetSpdAttr( PTARGET, SPD::TRPMIN_FINE_OFFSET, &(VAL), sizeof(VAL) ) #define ATTR_SPD_FINE_OFFSET_TRCMIN_GETMACRO(ID, PTARGET, VAL) \ + fapi::AttrOverrideSync::getAttrOverrideFunc(fapi::ID, PTARGET, &VAL) ? fapi::FAPI_RC_SUCCESS : \ fapi::platAttrSvc::fapiPlatGetSpdAttr( PTARGET, SPD::TRCMIN_FINE_OFFSET, &(VAL), sizeof(VAL) ) #define ATTR_SPD_NUM_OF_REGISTERS_USED_ON_RDIMM_GETMACRO(ID, PTARGET, VAL) \ + fapi::AttrOverrideSync::getAttrOverrideFunc(fapi::ID, PTARGET, &VAL) ? fapi::FAPI_RC_SUCCESS : \ fapi::platAttrSvc::fapiPlatGetSpdAttr( PTARGET, SPD::RMM_REGS_RDIMM, &(VAL), sizeof(VAL) ) #define ATTR_SPD_MODULE_SPECIFIC_SECTION_GETMACRO(ID, PTARGET, VAL) \ + fapi::AttrOverrideSync::getAttrOverrideFunc(fapi::ID, PTARGET, &VAL) ? fapi::FAPI_RC_SUCCESS : \ fapi::platAttrSvc::fapiPlatGetSpdAttr( PTARGET, SPD::MODULE_TYPE_SPECIFIC_SECTION, &(VAL), sizeof(VAL) ) #define ATTR_SPD_MODULE_ID_MODULE_MANUFACTURERS_JEDEC_ID_CODE_GETMACRO(ID, PTARGET, VAL) \ + fapi::AttrOverrideSync::getAttrOverrideFunc(fapi::ID, PTARGET, &VAL) ? fapi::FAPI_RC_SUCCESS : \ fapi::platAttrSvc::fapiPlatGetSpdAttr( PTARGET, SPD::MODULE_MANUFACTURER_ID, &(VAL), sizeof(VAL) ) #define ATTR_SPD_MODULE_ID_MODULE_MANUFACTURING_LOCATION_GETMACRO(ID, PTARGET, VAL) \ + fapi::AttrOverrideSync::getAttrOverrideFunc(fapi::ID, PTARGET, &VAL) ? fapi::FAPI_RC_SUCCESS : \ fapi::platAttrSvc::fapiPlatGetSpdAttr( PTARGET, SPD::MODULE_MANUFACTURING_LOCATION, &(VAL), sizeof(VAL) ) #define ATTR_SPD_MODULE_ID_MODULE_MANUFACTURING_DATE_GETMACRO(ID, PTARGET, VAL) \ + fapi::AttrOverrideSync::getAttrOverrideFunc(fapi::ID, PTARGET, &VAL) ? fapi::FAPI_RC_SUCCESS : \ fapi::platAttrSvc::fapiPlatGetSpdAttr( PTARGET, SPD::MODULE_MANUFACTURING_DATE, &(VAL), sizeof(VAL) ) #define ATTR_SPD_MODULE_ID_MODULE_SERIAL_NUMBER_GETMACRO(ID, PTARGET, VAL) \ + fapi::AttrOverrideSync::getAttrOverrideFunc(fapi::ID, PTARGET, &VAL) ? fapi::FAPI_RC_SUCCESS : \ fapi::platAttrSvc::fapiPlatGetSpdAttr( PTARGET, SPD::MODULE_SERIAL_NUMBER, &(VAL), sizeof(VAL) ) #define ATTR_SPD_CYCLICAL_REDUNDANCY_CODE_GETMACRO(ID, PTARGET, VAL) \ + fapi::AttrOverrideSync::getAttrOverrideFunc(fapi::ID, PTARGET, &VAL) ? fapi::FAPI_RC_SUCCESS : \ fapi::platAttrSvc::fapiPlatGetSpdAttr( PTARGET, SPD::MODULE_CRC, &(VAL), sizeof(VAL) ) #define ATTR_SPD_MODULE_PART_NUMBER_GETMACRO(ID, PTARGET, VAL) \ + fapi::AttrOverrideSync::getAttrOverrideFunc(fapi::ID, PTARGET, &VAL) ? fapi::FAPI_RC_SUCCESS : \ fapi::platAttrSvc::fapiPlatGetSpdAttr( PTARGET, SPD::MODULE_PART_NUMBER, &(VAL), sizeof(VAL) ) #define ATTR_SPD_MODULE_REVISION_CODE_GETMACRO(ID, PTARGET, VAL) \ + fapi::AttrOverrideSync::getAttrOverrideFunc(fapi::ID, PTARGET, &VAL) ? fapi::FAPI_RC_SUCCESS : \ fapi::platAttrSvc::fapiPlatGetSpdAttr( PTARGET, SPD::MODULE_REVISION_CODE, &(VAL), sizeof(VAL) ) #define ATTR_SPD_DRAM_MANUFACTURER_JEDEC_ID_CODE_GETMACRO(ID, PTARGET, VAL) \ + fapi::AttrOverrideSync::getAttrOverrideFunc(fapi::ID, PTARGET, &VAL) ? fapi::FAPI_RC_SUCCESS : \ fapi::platAttrSvc::fapiPlatGetSpdAttr( PTARGET, SPD::DRAM_MANUFACTURER_ID, &(VAL), sizeof(VAL) ) #define ATTR_SPD_BAD_DQ_DATA_GETMACRO(ID, PTARGET, VAL) \ + fapi::AttrOverrideSync::getAttrOverrideFunc(fapi::ID, PTARGET, &VAL) ? fapi::FAPI_RC_SUCCESS : \ fapi::platAttrSvc::fapiPlatGetSpdAttr( PTARGET, SPD::DIMM_BAD_DQ_DATA, &(VAL), sizeof(VAL) ) #define ATTR_SPD_BAD_DQ_DATA_SETMACRO(ID, PTARGET, VAL) \ + fapi::AttrOverrideSync::setAttrActionsFunc(fapi::ID, PTARGET, sizeof(VAL), &(VAL)), \ fapi::platAttrSvc::fapiPlatSetSpdAttr( PTARGET, SPD::DIMM_BAD_DQ_DATA, &(VAL), sizeof(VAL) ) //------------------------------------------------------------------------------ // MACROs to route ATTR Base Address accesses to the correct Hostboot function //------------------------------------------------------------------------------ #define ATTR_MSS_MEMORY_BASE_GETMACRO(ID, PTARGET, VAL) \ + fapi::AttrOverrideSync::getAttrOverrideFunc(fapi::ID, PTARGET, &VAL) ? fapi::FAPI_RC_SUCCESS : \ fapi::platAttrSvc::fapiPlatGetMemoryBaseAddr(PTARGET, VAL) #define ATTR_MSS_MIRROR_BASE_GETMACRO(ID, PTARGET, VAL) \ + fapi::AttrOverrideSync::getAttrOverrideFunc(fapi::ID, PTARGET, &VAL) ? fapi::FAPI_RC_SUCCESS : \ fapi::platAttrSvc::fapiPlatGetMirrorBaseAddr(PTARGET, VAL) //------------------------------------------------------------------------------ @@ -561,78 +613,97 @@ fapi::ReturnCode fapiPlatGetProcPcieBarSize ( // function //------------------------------------------------------------------------------ #define ATTR_CEN_DQ_TO_DIMM_CONN_DQ_GETMACRO(ID, PTARGET, VAL) \ + fapi::AttrOverrideSync::getAttrOverrideFunc(fapi::ID, PTARGET, &VAL) ? fapi::FAPI_RC_SUCCESS : \ fapi::platAttrSvc::fapiPlatGetDqMapping(PTARGET, VAL) //------------------------------------------------------------------------------ // MACRO to route ATTR_NAME access to the correct Hostboot function //------------------------------------------------------------------------------ #define ATTR_NAME_GETMACRO(ID, PTARGET, VAL) \ + fapi::AttrOverrideSync::getAttrOverrideFunc(fapi::ID, PTARGET, &VAL) ? fapi::FAPI_RC_SUCCESS : \ fapi::platAttrSvc::fapiPlatGetTargetName(PTARGET, VAL) //------------------------------------------------------------------------------ // MACRO to route ATTR_FUNCTIONAL access to the correct Hostboot function //------------------------------------------------------------------------------ #define ATTR_FUNCTIONAL_GETMACRO(ID, PTARGET, VAL) \ + fapi::AttrOverrideSync::getAttrOverrideFunc(fapi::ID, PTARGET, &VAL) ? fapi::FAPI_RC_SUCCESS : \ fapi::platAttrSvc::fapiPlatGetFunctional(PTARGET, VAL) //------------------------------------------------------------------------------ // MACRO to route ATTR_POS access to the correct Hostboot function //------------------------------------------------------------------------------ #define ATTR_POS_GETMACRO(ID, PTARGET, VAL) \ + fapi::AttrOverrideSync::getAttrOverrideFunc(fapi::ID, PTARGET, &VAL) ? fapi::FAPI_RC_SUCCESS : \ fapi::platAttrSvc::fapiPlatGetTargetPos(PTARGET, VAL) //------------------------------------------------------------------------------ // MACROS to support proc_setup_bars_memory_attributes.xml //------------------------------------------------------------------------------ #define ATTR_PROC_FOREIGN_NEAR_BASE_GETMACRO( ID, PTARGET, VAL ) \ + fapi::AttrOverrideSync::getAttrOverrideFunc(fapi::ID, PTARGET, &VAL) ? fapi::FAPI_RC_SUCCESS : \ fapi::platAttrSvc::fapiPlatGetProcForeignNearBase (PTARGET, VAL ) #define ATTR_PROC_FOREIGN_NEAR_SIZE_GETMACRO( ID, PTARGET, VAL ) \ + fapi::AttrOverrideSync::getAttrOverrideFunc(fapi::ID, PTARGET, &VAL) ? fapi::FAPI_RC_SUCCESS : \ fapi::platAttrSvc::fapiPlatGetProcForeignNearSize (PTARGET, VAL ) #define ATTR_PROC_FOREIGN_FAR_BASE_GETMACRO( ID, PTARGET, VAL ) \ + fapi::AttrOverrideSync::getAttrOverrideFunc(fapi::ID, PTARGET, &VAL) ? fapi::FAPI_RC_SUCCESS : \ fapi::platAttrSvc::fapiPlatGetProcForeignFarBase (PTARGET, VAL ) #define ATTR_PROC_FOREIGN_FAR_SIZE_GETMACRO( ID, PTARGET, VAL ) \ + fapi::AttrOverrideSync::getAttrOverrideFunc(fapi::ID, PTARGET, &VAL) ? fapi::FAPI_RC_SUCCESS : \ fapi::platAttrSvc::fapiPlatGetProcForeignFarSize (PTARGET, VAL ) #define ATTR_PROC_HA_BASE_GETMACRO( ID, PTARGET, VAL ) \ + fapi::AttrOverrideSync::getAttrOverrideFunc(fapi::ID, PTARGET, &VAL) ? fapi::FAPI_RC_SUCCESS : \ fapi::platAttrSvc::fapiPlatGetProcHaBase (PTARGET, VAL ) #define ATTR_PROC_HA_SIZE_GETMACRO( ID, PTARGET, VAL ) \ + fapi::AttrOverrideSync::getAttrOverrideFunc(fapi::ID, PTARGET, &VAL) ? fapi::FAPI_RC_SUCCESS : \ fapi::platAttrSvc::fapiPlatGetProcHaSize (PTARGET, VAL ) //------------------------------------------------------------------------------ // MACROS to support proc_setup_bars_mmio_attributes.xml //------------------------------------------------------------------------------ #define ATTR_PROC_PSI_BRIDGE_BAR_ENABLE_GETMACRO( ID, PTARGET, VAL ) \ + fapi::AttrOverrideSync::getAttrOverrideFunc(fapi::ID, PTARGET, &VAL) ? fapi::FAPI_RC_SUCCESS : \ fapi::platAttrSvc::fapiPlatGetProcPsiBridgeBarEnable (PTARGET, VAL ) #define ATTR_PROC_FSP_BAR_ENABLE_GETMACRO( ID, PTARGET, VAL ) \ + fapi::AttrOverrideSync::getAttrOverrideFunc(fapi::ID, PTARGET, &VAL) ? fapi::FAPI_RC_SUCCESS : \ fapi::platAttrSvc::fapiPlatGetProcFspBarEnable (PTARGET, VAL ) #define ATTR_PROC_INTP_BAR_ENABLE_GETMACRO( ID, PTARGET, VAL ) \ + fapi::AttrOverrideSync::getAttrOverrideFunc(fapi::ID, PTARGET, &VAL) ? fapi::FAPI_RC_SUCCESS : \ fapi::platAttrSvc::fapiPlatGetProcIntpBarEnable (PTARGET, VAL ) #define ATTR_PROC_NX_MMIO_BAR_ENABLE_GETMACRO( ID, PTARGET, VAL ) \ + fapi::AttrOverrideSync::getAttrOverrideFunc(fapi::ID, PTARGET, &VAL) ? fapi::FAPI_RC_SUCCESS : \ fapi::platAttrSvc::fapiPlatGetProcNxMmioBarEnable(PTARGET, VAL ) #define ATTR_PROC_NX_MMIO_BAR_SIZE_GETMACRO( ID, PTARGET, VAL ) \ + fapi::AttrOverrideSync::getAttrOverrideFunc(fapi::ID, PTARGET, &VAL) ? fapi::FAPI_RC_SUCCESS : \ fapi::platAttrSvc::fapiPlatGetProcNxMmioBarSize (PTARGET, VAL ) #define ATTR_PROC_PCIE_BAR_ENABLE_GETMACRO( ID, PTARGET, VAL ) \ + fapi::AttrOverrideSync::getAttrOverrideFunc(fapi::ID, PTARGET, &VAL) ? fapi::FAPI_RC_SUCCESS : \ fapi::platAttrSvc::fapiPlatGetProcPcieBarEnable (PTARGET, VAL ) #define ATTR_PROC_PCIE_BAR_BASE_ADDR_GETMACRO( ID, PTARGET, VAL ) \ + fapi::AttrOverrideSync::getAttrOverrideFunc(fapi::ID, PTARGET, &VAL) ? fapi::FAPI_RC_SUCCESS : \ fapi::platAttrSvc::fapiPlatGetProcPcieBarBaseAddr (PTARGET, VAL ) #define ATTR_PROC_PCIE_BAR_SIZE_GETMACRO( ID, PTARGET, VAL ) \ + fapi::AttrOverrideSync::getAttrOverrideFunc(fapi::ID, PTARGET, &VAL) ? fapi::FAPI_RC_SUCCESS : \ fapi::platAttrSvc::fapiPlatGetProcPcieBarSize (PTARGET, VAL ) //------------------------------------------------------------------------------ -// MACROS to support proc_fab_smp_fabric_attributes.xml -//------------------------------------------------------------------------------ - -//------------------------------------------------------------------------------ // MACROS to support enable attributes in p8_xip_customize_attributes.xml //------------------------------------------------------------------------------ #define ATTR_PROC_NX_ENABLE_GETMACRO( ID, PTARGET, VAL ) \ + fapi::AttrOverrideSync::getAttrOverrideFunc(fapi::ID, PTARGET, &VAL) ? fapi::FAPI_RC_SUCCESS : \ fapi::platAttrSvc::fapiPlatGetEnableAttr ( fapi::ID, PTARGET, VAL ) #define ATTR_PROC_PCIE_ENABLE_GETMACRO( ID, PTARGET, VAL ) \ + fapi::AttrOverrideSync::getAttrOverrideFunc(fapi::ID, PTARGET, &VAL) ? fapi::FAPI_RC_SUCCESS : \ fapi::platAttrSvc::fapiPlatGetEnableAttr ( fapi::ID, PTARGET, VAL ) #define ATTR_PROC_L3_ENABLE_GETMACRO( ID, PTARGET, VAL ) \ + fapi::AttrOverrideSync::getAttrOverrideFunc(fapi::ID, PTARGET, &VAL) ? fapi::FAPI_RC_SUCCESS : \ fapi::platAttrSvc::fapiPlatGetEnableAttr ( fapi::ID, PTARGET, VAL ) #define ATTR_PROC_A_ENABLE_GETMACRO( ID, PTARGET, VAL ) \ + fapi::AttrOverrideSync::getAttrOverrideFunc(fapi::ID, PTARGET, &VAL) ? fapi::FAPI_RC_SUCCESS : \ fapi::platAttrSvc::fapiPlatGetEnableAttr ( fapi::ID, PTARGET, VAL ) #define ATTR_PROC_X_ENABLE_GETMACRO( ID, PTARGET, VAL ) \ + fapi::AttrOverrideSync::getAttrOverrideFunc(fapi::ID, PTARGET, &VAL) ? fapi::FAPI_RC_SUCCESS : \ fapi::platAttrSvc::fapiPlatGetEnableAttr ( fapi::ID, PTARGET, VAL ) #endif // FAPIPLATATTRIBUTESERVICE_H_ diff --git a/src/include/usr/hwpf/plat/fapiPlatHwpExecutor.H b/src/include/usr/hwpf/plat/fapiPlatHwpExecutor.H index bbc0f827b..ee9f0ed88 100644 --- a/src/include/usr/hwpf/plat/fapiPlatHwpExecutor.H +++ b/src/include/usr/hwpf/plat/fapiPlatHwpExecutor.H @@ -5,7 +5,7 @@ /* */ /* IBM CONFIDENTIAL */ /* */ -/* COPYRIGHT International Business Machines Corp. 2011,2012 */ +/* COPYRIGHT International Business Machines Corp. 2011,2013 */ /* */ /* p1 */ /* */ @@ -38,7 +38,6 @@ #include <fapiTestHwpError.H> #include <fapiTestHwpFfdc.H> #include <fapiTestHwpConfig.H> -#include <fapiTestHwpAttr.H> #include <fapiTestHwpDq.H> #include <dimmBadDqBitmapAccessHwp.H> #include <erepairGetFailedLanesHwp.H> diff --git a/src/include/usr/hwpf/hwp/fapiTestHwpAttr.H b/src/include/usr/targeting/adapters/mutexadapter.H index ba28e440e..c0fda2408 100755..100644 --- a/src/include/usr/hwpf/hwp/fapiTestHwpAttr.H +++ b/src/include/usr/targeting/adapters/mutexadapter.H @@ -1,11 +1,11 @@ /* IBM_PROLOG_BEGIN_TAG */ /* This is an automatically generated prolog. */ /* */ -/* $Source: src/include/usr/hwpf/hwp/fapiTestHwpAttr.H $ */ +/* $Source: src/include/usr/targeting/adapters/mutexadapter.H $ */ /* */ /* IBM CONFIDENTIAL */ /* */ -/* COPYRIGHT International Business Machines Corp. 2011,2012 */ +/* COPYRIGHT International Business Machines Corp. 2013 */ /* */ /* p1 */ /* */ @@ -20,41 +20,30 @@ /* Origin: 30 */ /* */ /* IBM_PROLOG_END_TAG */ +#ifndef __TARGETING_MUTEXADAPTER_H +#define __TARGETING_MUTEXADAPTER_H + /** - * @file fapiTestHwpAttr.H - * - * @brief Defines a test Hardware Procedure that exercises the test attributes - */ +* @file mutexAdapter.H +* +* @brief Provides Hostboot specific TARGETING Mutex +*/ -/* - * Change Log ****************************************************************** - * Flag Defect/Feature User Date Description - * ------ -------------- ---------- ----------- ---------------------------- - * mjjones 06/30/2011 Created. - * mjjones 10/07/2011 Removed target param - * mjjones 10/17/2011 Added func pointer - */ +#include <sys/sync.h> -#ifndef FAPITESTHWPATTR_H_ -#define FAPITESTHWPATTR_H_ +#define TARG_MUTEX_TYPE \ + mutex_t -#include <fapi.H> +#define TARG_MUTEX_INIT(_t) \ + mutex_init(&(_t)) -typedef fapi::ReturnCode (*hwpTestAttributes_FP_t)(); +#define TARG_MUTEX_DESTROY(_t) \ + mutex_destroy(&(_t)) -extern "C" -{ +#define TARG_MUTEX_LOCK(_t) \ + mutex_lock(&(_t)) -/** - * @brief HWP that exercises attributes - * - * @param[in] i_mbaTarget Reference to MBA chiplet target - * @param[in] i_procTarget Reference to processor chip target - * @return ReturnCode - */ -fapi::ReturnCode hwpTestAttributes(fapi::Target & i_mbaTarget, - fapi::Target & i_procTarget); - -} +#define TARG_MUTEX_UNLOCK(_t) \ + mutex_unlock(&(_t)) #endif diff --git a/src/include/usr/targeting/common/attributeTank.H b/src/include/usr/targeting/common/attributeTank.H new file mode 100644 index 000000000..3fea178c7 --- /dev/null +++ b/src/include/usr/targeting/common/attributeTank.H @@ -0,0 +1,342 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/include/usr/targeting/common/attributeTank.H $ */ +/* */ +/* IBM CONFIDENTIAL */ +/* */ +/* COPYRIGHT International Business Machines Corp. 2013 */ +/* */ +/* p1 */ +/* */ +/* Object Code Only (OCO) source materials */ +/* Licensed Internal Code Source Materials */ +/* IBM HostBoot Licensed Internal Code */ +/* */ +/* 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. */ +/* */ +/* Origin: 30 */ +/* */ +/* IBM_PROLOG_END_TAG */ +/** + * @file attributeTank.H + * + * @brief Defines the AttributeTank and its associated classes. These are used + * to store attributes for Attribute Overriding and Synchronization + */ + +/* + * Change Log ****************************************************************** + * Flag Defect/Feature User Date Description + * ------ -------------- ---------- ----------- ---------------------------- + * mjjones 06/07/2012 Created + * mjjones 10/15/2012 Moved to general AttributeTank. + * mjjones 02/13/2013 Moved to Targeting and major + * design changes + */ + +#ifndef __TARGETING_COMMON_ATTRTANK_H +#define __TARGETING_COMMON_ATTRTANK_H + +#include <stdint.h> +#include <list> +#include <vector> +#include <targeting/adapters/mutexadapter.H> + +namespace TARGETING +{ + +/** + * @class AttributeTank + * + * This class is used to store Attributes + */ +class AttributeTank +{ +public: + /** + * @brief Allocation types + * + * This is passed to serializeAttributes + */ + enum AllocType + { + ALLOC_TYPE_MALLOC = 1, + ALLOC_TYPE_NEW = 2, + }; + + /** + * @enum AttributeFlags + * + * Enumeration of the possible attribute flags. This is a bitmap + * + * This is passed to setAttribute + */ + enum AttributeFlags + { + ATTR_FLAG_CONST = 0x01, // Use-case is a constant Attribute Override + // NEXT = 0x02, + // NEXT = 0x04, + // NEXT = 0x08, + }; + + /** + * @enum TankLayer + * + * Enumeration of the software layers that contain AttributeTanks + */ + enum TankLayer + { + TANK_LAYER_NONE, + TANK_LAYER_FAPI, + TANK_LAYER_TARG, + }; + + // Constants for various fields in AttributeHeader + static const uint16_t ATTR_POS_NA = 0xffff; // iv_pos N/A + static const uint8_t ATTR_UNIT_POS_NA = 0xff; // iv_unitPos N/A + + /** + * @struct AttributeHeader + * + * This structure defines all the data for an attribute without the actual + * attribute value. + * + * This is used in an AttributeSerializedChunk and used to store attributes + * in an AttributeTank + */ + struct AttributeHeader + { + /** + * @brief Constructor + */ + AttributeHeader(); + + // Public data + uint32_t iv_attrId; // Attribute ID + uint32_t iv_targetType; // Target Type attribute is for + uint16_t iv_pos; // For chips/dimms the position + // For chiplets the parent chip position + uint8_t iv_unitPos; // For chiplets the position + uint8_t iv_flags; // AttributeFlags enum value(s) + uint32_t iv_valSize; // Size of the attribute value in bytes + }; + + /** + * @struct AttributeSerializedChunk + * + * This structure defines a chunk of memory for containing serialized + * attributes. The memory chunk contains a set of attributes, each is an + * AttributeHeader followed by a buffer containing the attribute value. + * + * A vector of AttributeSerializedChunks is returned by serializeAttributes + * and a single AttributeSerializedChunk is passed to deserializeAttributes + * + * The user must free the memory pointed to by iv_pAttributes before + * deleting this structure, the reason is that the allocType (malloc/new) + * and therefore the free type (free/delete[]) was specified in + * serializeAttributes and the use case is to pass attributes over a + * mailbox interface which may free memory automatically. + */ + struct AttributeSerializedChunk + { + /** + * @brief Constructor + */ + AttributeSerializedChunk(); + + uint32_t iv_size; // Chunk size in bytes + uint8_t * iv_pAttributes; // Pointer to chunk of memory + }; + + /** + * @brief Default constructor + */ + AttributeTank(); + + /** + * @brief Destructor. Deletes all Attributes + */ + virtual ~AttributeTank(); + + /** + * @brief Checks if the platform has enabled synchronization + * + * Can be called before storing attributes in a tank for the purposes of + * synchronization. + */ + static bool syncEnabled(); + + /** + * @brief Clear all attributes + */ + virtual void clearAllAttributes(); + + /** + * @brief Clear any non-const attribute for a specified ID and Target + * + * This is called on an OverrideAttributeTank to clear any non-const + * Attribute Override when an attribute is set + * + * @param[in] i_attrId Attribute ID + * @param[in] i_targetType Target Type attribute is for + * @param[in] i_pos Target Position + * @param[in] i_unitPos Target Unit Position + */ + virtual void clearNonConstAttribute(const uint32_t i_attrId, + const uint32_t i_targetType, + const uint16_t i_pos, + const uint8_t i_unitPos); + + /** + * @brief Set an Attribute + * + * The attribute value is copied from i_pVal. If the attribute already + * exists then it is replaced with the new one + * + * This is called on an OverrideAttributeTank to setup an override. + * + * This is called on a SyncAttributeTank to save an Attribute for syncing + * when an attribute is set + * + * @param[in] i_attrId Attribute ID + * @param[in] i_targetType Target Type attribute is for + * @param[in] i_pos Target Position + * @param[in] i_unitPos Target Unit Position + * @param[in] i_flags Flags (ORed set of AttributeFlags) + * @param[in] i_valSize Size of attribute value in bytes + * @param[in] i_pVal Pointer to attribute value + */ + virtual void setAttribute(const uint32_t i_attrId, + const uint32_t i_targetType, + const uint16_t i_pos, + const uint8_t i_unitPos, + const uint8_t i_flags, + const uint32_t i_valSize, + const void * i_pVal); + + /** + * @brief Get a copy of an Attribute + * + * This is called on an OverrideAttributeTank to query/get an Attribute + * Override when an attribute is got + * + * @param[in] i_attrId Attribute ID + * @param[in] i_targetType Target Type attribute is for + * @param[in] i_pos Target Position + * @param[in] i_unitPos Target Unit Position + * @param[out] o_pVal Pointer to attribute value + * + * return true if attribute exists and a copy was written to o_pVal + */ + virtual bool getAttribute(const uint32_t i_attrId, + const uint32_t i_targetType, + const uint16_t i_pos, + const uint8_t i_unitPos, + void * o_pVal) const; + + /** + * @brief Serialize all Attributes into newly allocated memory chunks + * + * The use case is for getting the attributes to send across an interface + * to another AttributeTank on a another subsystem. The alloc type can be + * specified to support interface code that automatically frees buffers + * after sending (Hostboot mailbox uses malloc/free, FSP mailbox uses + * new[]/delete[]). + * + * @param[in] i_allocType Which allocation is used to allocated memory + * @param[in] i_chunkSize Max chunk size to use + * @param[out] o_attributes Ref to vector that AttributeSerializedChunk + * structs are added to. + * The caller must free (if MALLOC) + * or delete[] (if NEW) each chunk's memory + */ + virtual void serializeAttributes( + const AllocType i_allocType, + const uint32_t i_chunkSize, + std::vector<AttributeSerializedChunk> & o_attributes) const; + + /** + * @brief Deserialize a chunk of Attributes into the tank + * + * The use case is for receiving a chunk of serialized attributes from + * another AttributeTank on a another subsystem. The caller is responsible + * for freeing/deleting the memory in the chunk after calling this function. + * + * @param[in] i_attributes Reference to AttributeSerializedChunk containing + * attributes. + */ + virtual void deserializeAttributes( + const AttributeSerializedChunk & i_attributes); + + /** + * @brief Fast inline check if any attributes exist in the tank + * + * The use case is for performing a very fast check to see if attributes + * exist in the tank before calling attributeExists to check that an + * attribute with the specified ID exists in the tank. This is done without + * a lock for maximum performance. + * + * return true if any attributes exist + */ + virtual bool attributesExist() const { return iv_attributesExist; } + + /** + * @brief Check if an attribute exists in the tank + * + * The use case is for performing a check to see if the specified attribute + * exists in the tank before doing the work to figure out a Target's type/ + * position and calling a function to clear or get attributes. The user is + * expected to call attributesExist() to check if any attributes exist in + * the tank before calling this function. + * + * @param[in] i_attrId Attribute ID + * + * return true if any attributes exist + */ + virtual bool attributeExists(const uint32_t i_attrId) const; + +private: + // Copy constructor and assignment operator disabled + AttributeTank(const AttributeTank & i_right); + AttributeTank & operator=(const AttributeTank & i_right); + + /** + * @struct Attribute + * + * This structure defines a single attribute. + */ + struct Attribute + { + /** + * @brief Constructor + */ + Attribute(); + + /** + * @brief Destructor. Frees memory + */ + ~Attribute(); + + // Public data + AttributeHeader iv_hdr; + uint8_t * iv_pVal; // Pointer to attribute value + }; + + // The attributes + // Note: A possible performance boost could be to store the elements in a + // map, the key could be a sub-structure. + bool iv_attributesExist; + std::list<Attribute *> iv_attributes; + typedef std::list<Attribute *>::iterator AttributesItr_t; + typedef std::list<Attribute *>::const_iterator AttributesCItr_t; + + // Lock for thread safety (class provided by platform) + mutable TARG_MUTEX_TYPE iv_mutex; +}; + +} // namespace TARGETING + +#endif diff --git a/src/include/usr/targeting/common/target.H b/src/include/usr/targeting/common/target.H index a3dbc8041..16b2a8c51 100644 --- a/src/include/usr/targeting/common/target.H +++ b/src/include/usr/targeting/common/target.H @@ -48,6 +48,7 @@ // This component #include <targeting/common/attributes.H> +#include <targeting/common/attributeTank.H> namespace TARGETING { @@ -269,6 +270,26 @@ class Target */ Target* getTargetFromHuid(const ATTR_HUID_type i_huid) const; + /** + * @brief Return the Targeting Override Attribute Tank + * + * @return Reference to the Attribute Tank + */ + static AttributeTank & theTargOverrideAttrTank() + { + return cv_overrideTank; + } + + /** + * @brief Return the Targeting Sync Attribute Tank + * + * @return Reference to the Attribute Tank + */ + static AttributeTank & theTargSyncAttrTank() + { + return cv_syncTank; + } + private: // Private helper interfaces /** @@ -378,6 +399,39 @@ class Target const ATTRIBUTE_ID i_attribute, mutex_t*& o_pMutex) const; + /** + * @brief Returns the target's type as used in an attribute tank. + * + * This target type is associated with an attribute in an attribute + * tank and helps identify which target(s) the attribute belongs to + * + * @return uint32_t The target type + */ + uint32_t getAttrTankTargetType() const; + + /** + * @brief Returns the target's position as used in an attribute tank. + * + * This target position is associated with an attribute in an attribute + * tank and helps identify which target(s) the attribute belongs to. + * For a unit, this is the parent chip's position + * + * @return uint16_t The target position + */ + uint16_t getAttrTankTargetPos() const; + + /** + * @brief Returns the target's unit position as used in an attribute + * tank. + * + * This target unit position is associated with an attribute in an + * attribute tank and helps identify which target(s) the attribute + * belongs to. This is only a valid value for units + * + * @return uint8_t The target unit position + */ + uint8_t getAttrTankTargetUnitPos() const; + private: // Private instance variables uint32_t iv_attrs; ///< Total attributes allowed for this @@ -407,6 +461,12 @@ class Target Target& operator=( const Target& i_right); + private: // Private class variables + + // Attribute Tanks + static AttributeTank cv_overrideTank; + static AttributeTank cv_syncTank; + friend class PnorBuilderService; } PACKED; diff --git a/src/usr/hwpf/fapi/fapiAttributeTank.C b/src/usr/hwpf/fapi/fapiAttributeTank.C deleted file mode 100644 index a2f84f68d..000000000 --- a/src/usr/hwpf/fapi/fapiAttributeTank.C +++ /dev/null @@ -1,458 +0,0 @@ -/* IBM_PROLOG_BEGIN_TAG */ -/* This is an automatically generated prolog. */ -/* */ -/* $Source: src/usr/hwpf/fapi/fapiAttributeTank.C $ */ -/* */ -/* IBM CONFIDENTIAL */ -/* */ -/* COPYRIGHT International Business Machines Corp. 2012 */ -/* */ -/* p1 */ -/* */ -/* Object Code Only (OCO) source materials */ -/* Licensed Internal Code Source Materials */ -/* IBM HostBoot Licensed Internal Code */ -/* */ -/* 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. */ -/* */ -/* Origin: 30 */ -/* */ -/* IBM_PROLOG_END_TAG */ -/** - * @file fapiAttributeTank.C - * - * @brief Implements the AttributeTank and Attribute classes. - */ - -/* - * Change Log ****************************************************************** - * Flag Defect/Feature User Date Description - * ------ -------------- ---------- ----------- ---------------------------- - * mjjones 06/07/2012 Created - */ -#include <stdlib.h> -#include <fapiAttributeTank.H> -#include <fapiAttributeService.H> -#include <fapiPlatTrace.H> -#include <fapiReturnCode.H> -#include <fapiSystemConfig.H> - -namespace fapi -{ - -//****************************************************************************** -Attribute::Attribute() : - iv_val(0), iv_attrId(0), iv_targetType(0), iv_pos(0), iv_unitPos(0), - iv_flags(0), iv_arrayD1(0), iv_arrayD2(0), iv_arrayD3(0), iv_arrayD4(0) -{ - -} - -//****************************************************************************** -AttributeChunk::AttributeChunk() : - iv_numAttributes(0), iv_pAttributes(NULL) -{ - -} - -//****************************************************************************** -AttributeTank::AttributeTank() : - iv_pName("AttributeTank"), iv_attributesExist(false) -{ - FAPI_IMP("AttributeTank: Constructor"); -} - -//****************************************************************************** -AttributeTank::~AttributeTank() -{ - FAPI_IMP("AttributeTank: Destructor"); -} - -//****************************************************************************** -void AttributeTank::clearAllAttributes() -{ - platLock(); - FAPI_DBG("%s: Clearing all attributes", iv_pName); - iv_attributesExist = false; - iv_attributes.clear(); - platUnlock(); -} - -//****************************************************************************** -void AttributeTank::clearNonConstAttribute(const fapi::AttributeId i_attrId, - const fapi::Target * const i_pTarget) -{ - // Do a quick check to see if any attributes exist. This is deliberately - // done without a lock for performance. The use-case for this function is - // FAPI_ATTR_SET calling to clear any constant override, overrides should - // not be changed while HWPs are setting attributes, but even if they are - // there is no risk of corruption. - if (!iv_attributesExist) - { - return; - } - - uint32_t l_targetType = getTargetType(i_pTarget); - uint16_t l_pos = getTargetPos(i_pTarget); - uint8_t l_unitPos = getTargetUnitPos(i_pTarget); - - platLock(); - - // Note that for an array attribute, there will be multiple Attribute - // objects, one for each element - AttributesItr_t l_itr = iv_attributes.begin(); - - while (l_itr != iv_attributes.end()) - { - if ( (!((*l_itr).iv_flags & ATTR_FLAG_CONST)) && - ((*l_itr).iv_attrId == static_cast<uint32_t>(i_attrId)) && - ((*l_itr).iv_targetType == l_targetType) && - ((*l_itr).iv_pos == l_pos) && - ((*l_itr).iv_unitPos == l_unitPos) ) - { - FAPI_INF("%s: Clearing non-const attr 0x%x", iv_pName, i_attrId); - l_itr = iv_attributes.erase(l_itr); - } - else - { - ++l_itr; - } - } - - if (iv_attributes.empty()) - { - iv_attributesExist = false; - } - - platUnlock(); -} - -//****************************************************************************** -void AttributeTank::setAttribute(const fapi::AttributeId i_attrId, - const fapi::Target * const i_pTarget, - const uint64_t i_val, - const uint8_t i_arrayD1, - const uint8_t i_arrayD2, - const uint8_t i_arrayD3, - const uint8_t i_arrayD4) -{ - // Create an Attribute structure - Attribute l_attr; - - l_attr.iv_val = i_val; - l_attr.iv_attrId = i_attrId; - l_attr.iv_targetType = getTargetType(i_pTarget); - l_attr.iv_pos = getTargetPos(i_pTarget); - l_attr.iv_unitPos = getTargetUnitPos(i_pTarget); - l_attr.iv_flags = 0; - l_attr.iv_arrayD1 = i_arrayD1; - l_attr.iv_arrayD2 = i_arrayD2; - l_attr.iv_arrayD3 = i_arrayD3; - l_attr.iv_arrayD4 = i_arrayD4; - - // Set the attribute in the tank - setAttribute(l_attr); -} - -//****************************************************************************** -void AttributeTank::setAttribute(const Attribute & i_attribute) -{ - platLock(); - - // Search for an existing matching attribute - bool l_found = false; - AttributesItr_t l_itr = iv_attributes.begin(); - - for (AttributesItr_t l_itr = iv_attributes.begin(); l_itr - != iv_attributes.end(); ++l_itr) - { - if ( ((*l_itr).iv_attrId == i_attribute.iv_attrId) && - ((*l_itr).iv_targetType == i_attribute.iv_targetType) && - ((*l_itr).iv_pos == i_attribute.iv_pos) && - ((*l_itr).iv_unitPos == i_attribute.iv_unitPos) && - ((*l_itr).iv_arrayD1 == i_attribute.iv_arrayD1) && - ((*l_itr).iv_arrayD2 == i_attribute.iv_arrayD2) && - ((*l_itr).iv_arrayD3 == i_attribute.iv_arrayD3) && - ((*l_itr).iv_arrayD4 == i_attribute.iv_arrayD4) ) - { - // Found existing attribute, update it unless the existing attribute - // is const and the new attribute is non-const - if (!( ((*l_itr).iv_flags & ATTR_FLAG_CONST) && - (!(i_attribute.iv_flags & ATTR_FLAG_CONST)) ) ) - { - FAPI_DBG("%s: Updating attr 0x%x", iv_pName, - i_attribute.iv_attrId); - (*l_itr).iv_flags = i_attribute.iv_flags; - (*l_itr).iv_val = i_attribute.iv_val; - } - l_found = true; - break; - } - } - - if (!l_found) - { - // Add the attribute to the tank - FAPI_DBG("%s: Setting attr 0x%x", iv_pName, i_attribute.iv_attrId); - iv_attributesExist = true; - iv_attributes.push_back(i_attribute); - } - - platUnlock(); -} - -//****************************************************************************** -bool AttributeTank::getAttribute(const fapi::AttributeId i_attrId, - const fapi::Target * const i_pTarget, - uint64_t & o_val, - const uint8_t i_arrayD1, - const uint8_t i_arrayD2, - const uint8_t i_arrayD3, - const uint8_t i_arrayD4) const -{ - // Do a quick check to see if any attributes exist. This is deliberately - // done without a lock for performance. The use-case for this function is - // FAPI_ATTR_GET calling to get an override, overrides should not be changed - // while HWPs are getting attributes, but even if they are there is no risk - // of corruption. - if (!iv_attributesExist) - { - return false; - } - - // Do not return any override for ATTR_POS or ATTR_CHIP_UNIT_POS because - // this function calls getTargetPos and getTargetUnitPos which will query - // ATTR_POS and ATTR_CHIP_UNIT_POS again resulting in an infinite loop - if ((i_attrId == ATTR_POS) || (i_attrId == ATTR_CHIP_UNIT_POS)) - { - return false; - } - - bool l_found = false; - uint32_t l_targetType = getTargetType(i_pTarget); - uint16_t l_pos = getTargetPos(i_pTarget); - uint8_t l_unitPos = getTargetUnitPos(i_pTarget); - - platLock(); - - for (AttributesCItr_t l_itr = iv_attributes.begin(); l_itr - != iv_attributes.end(); ++l_itr) - { - if ( ((*l_itr).iv_attrId == static_cast<uint32_t>(i_attrId)) && - ((*l_itr).iv_targetType == l_targetType) && - (((*l_itr).iv_pos == ATTR_POS_NA) || ((*l_itr).iv_pos == l_pos)) && - (((*l_itr).iv_unitPos == ATTR_UNIT_POS_NA) || - ((*l_itr).iv_unitPos == l_unitPos)) && - ((*l_itr).iv_arrayD1 == i_arrayD1) && - ((*l_itr).iv_arrayD2 == i_arrayD2) && - ((*l_itr).iv_arrayD3 == i_arrayD3) && - ((*l_itr).iv_arrayD4 == i_arrayD4) ) - { - FAPI_INF("%s: Getting attr 0x%x:0x%llx", iv_pName, i_attrId, - (*l_itr).iv_val); - l_found = true; - o_val = (*l_itr).iv_val; - break; - } - } - - platUnlock(); - return l_found; -} - -//****************************************************************************** -void AttributeTank::getAllAttributes( - const AllocType i_allocType, - std::vector<AttributeChunk> & o_attributes) const -{ - platLock(); - - FAPI_DBG("%s: Getting all attributes", iv_pName); - - if (iv_attributes.size()) - { - AttributesCItr_t l_itr = iv_attributes.begin(); - size_t l_numAttrsRemaining = iv_attributes.size(); - - while (l_numAttrsRemaining) - { - AttributeChunk l_chunk; - l_chunk.iv_numAttributes = l_numAttrsRemaining; - - if (l_chunk.iv_numAttributes > AttributeChunk::MAX_ATTRS_PER_CHUNK) - { - l_chunk.iv_numAttributes = AttributeChunk::MAX_ATTRS_PER_CHUNK; - } - - if (i_allocType == ALLOC_TYPE_MALLOC) - { - l_chunk.iv_pAttributes = static_cast<uint8_t *> - (malloc(sizeof(Attribute) * l_chunk.iv_numAttributes)); - } - else - { - l_chunk.iv_pAttributes = - new uint8_t[sizeof(Attribute) * l_chunk.iv_numAttributes]; - } - - Attribute * l_pAttr = reinterpret_cast<Attribute *> - (l_chunk.iv_pAttributes); - - for(size_t i = 0; i < l_chunk.iv_numAttributes; i++) - { - *l_pAttr++ = (*l_itr); - l_itr++; - } - - o_attributes.push_back(l_chunk); - l_numAttrsRemaining -= l_chunk.iv_numAttributes; - } - } - - platUnlock(); -} - -//****************************************************************************** -bool AttributeTank::attributesExist() -{ - platLock(); - bool l_attributesExist = iv_attributesExist; - platUnlock(); - return l_attributesExist; -} - -//****************************************************************************** -uint32_t AttributeTank::getTargetType(const fapi::Target * const i_pTarget) -{ - if (i_pTarget == NULL) - { - return static_cast<uint32_t>(TARGET_TYPE_SYSTEM); - } - else - { - return static_cast<uint32_t>(i_pTarget->getType()); - } -} - -//****************************************************************************** -uint16_t AttributeTank::getTargetPos(const fapi::Target * const i_pTarget) -{ - // Note that any errors querying a parent chip or a position attribute are - // ignored and the function returns ATTR_POS_NA - uint16_t l_ret = ATTR_POS_NA; - - if (i_pTarget != NULL) - { - ReturnCode l_rc; - uint32_t l_pos = 0xffffffff; - - if (i_pTarget->isChiplet()) - { - // Target is a chiplet, o_pos is the parent chip position - Target l_chip; - - l_rc = fapiGetParentChip(*i_pTarget, l_chip); - - if (l_rc) - { - FAPI_ERR("Error (0x%x) from fapiGetParentChip", - static_cast<uint32_t>(l_rc)); - } - else - { - l_rc = FAPI_ATTR_GET(ATTR_POS, &l_chip, l_pos); - - if (l_rc) - { - FAPI_ERR("Error (0x%x) getting parent chip position attr", - static_cast<uint32_t>(l_rc)); - } - else - { - l_ret = l_pos; - } - } - } - else - { - // Target is not a chiplet, iv_pos is the Target position - l_rc = FAPI_ATTR_GET(ATTR_POS, i_pTarget, l_pos); - - if (l_rc) - { - FAPI_ERR("Error (0x%x) getting position attr", - static_cast<uint32_t>(l_rc)); - } - else - { - l_ret = l_pos; - } - } - } - - return l_ret; -} - -//****************************************************************************** -uint8_t AttributeTank::getTargetUnitPos(const fapi::Target * const i_pTarget) -{ - // Note that any errors querying a position attribute are ignored and the - // function returns ATTR_UNIT_POS_NA - uint8_t l_ret = ATTR_UNIT_POS_NA; - - if (i_pTarget != NULL) - { - if (i_pTarget->isChiplet()) - { - uint8_t l_unitPos = 0xff; - - ReturnCode l_rc = FAPI_ATTR_GET(ATTR_CHIP_UNIT_POS, i_pTarget, - l_unitPos); - - if (l_rc) - { - FAPI_ERR("Error (0x%x) getting chiplet position attr", - static_cast<uint32_t>(l_rc)); - } - else - { - l_ret = l_unitPos; - } - } - } - - return l_ret; -} -//****************************************************************************** -OverrideAttributeTank::OverrideAttributeTank() -{ - iv_pName = "OverrideAttributeTank"; - FAPI_IMP("OverrideAttributeTank: Constructor"); -} - -//****************************************************************************** -SyncAttributeTank::SyncAttributeTank() -{ - iv_pName = "SyncAttributeTank"; - FAPI_IMP("SyncAttributeTank: Constructor"); -} - -//****************************************************************************** -void SyncAttributeTank::setAttribute(const fapi::AttributeId i_attrId, - const fapi::Target * const i_pTarget, - const uint64_t i_val, - const uint8_t i_arrayD1, - const uint8_t i_arrayD2, - const uint8_t i_arrayD3, - const uint8_t i_arrayD4) -{ - if (platSyncEnabled()) - { - AttributeTank::setAttribute(i_attrId, i_pTarget, i_val, i_arrayD1, - i_arrayD2, i_arrayD3, i_arrayD4); - } -} - -} diff --git a/src/usr/hwpf/fapi/fapiParseAttributeInfo.pl b/src/usr/hwpf/fapi/fapiParseAttributeInfo.pl index deb2fa174..0f3f10d1f 100755 --- a/src/usr/hwpf/fapi/fapiParseAttributeInfo.pl +++ b/src/usr/hwpf/fapi/fapiParseAttributeInfo.pl @@ -65,6 +65,8 @@ # mjjones 11/05/12 Generate fapiAttributeIds.txt # Generate fapiAttributeEnums.txt # mjjones 03/21/13 Add fapi namespace to Chip EC Feature macro +# mjjones 02/27/13 Generate fapiAttrInfo.csv +# Generate fapiAttrEnumInfo.csv # # End Change Log ****************************************************** @@ -83,8 +85,8 @@ if ($numArgs < 2) print (" - fapiAttributePlatCheck.H. Contains compile time checks that all attributes are\n"); print (" handled by the platform\n"); print (" - fapiAttributesSupported.html Contains the HWPF attributes supported\n"); - print (" - fapiAttributeIds.txt Used to xlate between AttrID string and value\n"); - print (" - fapiAttributeEnums.txt Used to xlate between AttrEnum string and value\n"); + print (" - fapiAttrInfo.csv Used to process Attribute Override Text files\n"); + print (" - fapiAttrEnumInfo.csv Used to process Attribute Override Text files\n"); exit(1); } @@ -130,12 +132,12 @@ open(ASFILE, ">", $asFile); my $itFile = $ARGV[0]; $itFile .= "/"; -$itFile .= "fapiAttributeIds.txt"; +$itFile .= "fapiAttrInfo.csv"; open(ITFILE, ">", $itFile); my $etFile = $ARGV[0]; $etFile .= "/"; -$etFile .= "fapiAttributeEnums.txt"; +$etFile .= "fapiAttrEnumInfo.csv"; open(ETFILE, ">", $etFile); #------------------------------------------------------------------------------ @@ -211,6 +213,28 @@ 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 @@ -258,8 +282,6 @@ foreach my $argnum (1 .. $#ARGV) exit(1); } - $attrIdHash{$attr->{id}} = 1; - # Calculate a 28 bit hash value. my $attrHash128Bit = md5_hex($attr->{id}); my $attrHash28Bit = substr($attrHash128Bit, 0, 7); @@ -267,9 +289,6 @@ foreach my $argnum (1 .. $#ARGV) # Print the attribute ID/value to fapiAttributeIds.H print AIFILE " $attr->{id} = 0x$attrHash28Bit,\n"; - # Print the attribute ID/value to fapiAttributeIds.txt - print ITFILE "$attr->{id} 0x$attrHash28Bit\n"; - if (exists($attrValHash{$attrHash28Bit})) { # Two different attributes generate the same hash-value! @@ -278,6 +297,7 @@ foreach my $argnum (1 .. $#ARGV) exit(1); } + $attrIdHash{$attr->{id}} = $attrHash28Bit; $attrValHash{$attrHash28Bit} = 1; }; } @@ -352,6 +372,7 @@ foreach my $argnum (1 .. $#ARGV) #---------------------------------------------------------------------- # Print the typedef for each attribute's val type to fapiAttributeIds.H + # Print the attribute information to fapiAttrInfo.csv #---------------------------------------------------------------------- if (exists $attr->{chipEcFeature}) { @@ -369,14 +390,20 @@ foreach my $argnum (1 .. $#ARGV) 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 '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"; } else { @@ -463,9 +490,9 @@ foreach my $argnum (1 .. $#ARGV) # Print the attribute enum to fapiAttributeIds.H print AIFILE " ENUM_$attr->{id}_${val}"; - # Print the attribute enum to fapiAttributeEnums.txt + # Print the attribute enum to fapiAttrEnumInfo.csv my $attrEnumTxt = "$attr->{id}_${val}\n"; - $attrEnumTxt =~ s/= //; + $attrEnumTxt =~ s/ = /,/; print ETFILE $attrEnumTxt; if ($attr->{valueType} eq 'uint64') diff --git a/src/usr/hwpf/fapi/makefile b/src/usr/hwpf/fapi/makefile index a6b5a3348..5af2f587f 100644 --- a/src/usr/hwpf/fapi/makefile +++ b/src/usr/hwpf/fapi/makefile @@ -36,7 +36,6 @@ OBJS = fapiReturnCode.o \ fapiErrorInfo.o \ fapiAttributeService.o \ fapiChipEcFeature.o \ - fapiAttributeTank.o \ fapiCollectRegFfdc.o include ${ROOTPATH}/config.mk diff --git a/src/usr/hwpf/hwp/fapiTestHwpAttr.C b/src/usr/hwpf/hwp/fapiTestHwpAttr.C deleted file mode 100755 index ad01d43c0..000000000 --- a/src/usr/hwpf/hwp/fapiTestHwpAttr.C +++ /dev/null @@ -1,1196 +0,0 @@ -/* IBM_PROLOG_BEGIN_TAG */ -/* This is an automatically generated prolog. */ -/* */ -/* $Source: src/usr/hwpf/hwp/fapiTestHwpAttr.C $ */ -/* */ -/* IBM CONFIDENTIAL */ -/* */ -/* COPYRIGHT International Business Machines Corp. 2011,2012 */ -/* */ -/* p1 */ -/* */ -/* Object Code Only (OCO) source materials */ -/* Licensed Internal Code Source Materials */ -/* IBM HostBoot Licensed Internal Code */ -/* */ -/* 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. */ -/* */ -/* Origin: 30 */ -/* */ -/* IBM_PROLOG_END_TAG */ -/** - * @file fapiTestHwpAttr.C - * - * @brief Implements the test Hardware Procedure that exercises the scratch - * attributes - */ - -/* - * Change Log ****************************************************************** - * Flag Defect/Feature User Date Description - * ------ -------------- ---------- ----------- ---------------------------- - * mjjones 06/30/2011 Created. - * mjjones 09/07/2011 Update to test scratch attrs - * mjjones 10/06/2011 Updates traces - * mjjones 10/07/2011 Removed target param - * mjjones 10/15/2011 Test scratch attributes - * mjjones 10/17/2011 Update scratch test - * camvanng 10/26/2011 Update scratch test - * mjjones 10/28/2011 Fix error generation - * camvanng 11/09/2011 Update attr enum test - * mjjones 11/17/2011 Removed some initfile attr tests - * mjjones 11/22/2011 Demonstrate use of heap based array - * mjjones 10/19/2012 Update AttributeTank tests - * - * HWP_IGNORE_VERSION_CHECK - */ - -#include <fapiTestHwpAttr.H> - -extern "C" -{ - -//****************************************************************************** -// hwpTestAttributes function -//****************************************************************************** -fapi::ReturnCode hwpTestAttributes(fapi::Target & i_mbaTarget, - fapi::Target & i_procTarget) -{ - FAPI_INF("hwpTestAttributes: Start HWP"); - fapi::ReturnCode l_rc; - - do - { - //---------------------------------------------------------------------- - // Test ATTR_SCRATCH_UINT8_1 - //---------------------------------------------------------------------- - { - uint8_t l_uint8 = 7; - - // Test set - l_rc = FAPI_ATTR_SET(ATTR_SCRATCH_UINT8_1, NULL, l_uint8); - if (l_rc) - { - FAPI_ERR("hwpTestAttributes: ATTR_SCRATCH_UINT8_1. Error from SET"); - break; - } - - // Test get - l_uint8 = 8; - l_rc = FAPI_ATTR_GET(ATTR_SCRATCH_UINT8_1, NULL, l_uint8); - if (l_rc) - { - FAPI_ERR("hwpTestAttributes: ATTR_SCRATCH_UINT8_1. Error from GET"); - break; - } - - // Check value - if (l_uint8 != 7) - { - FAPI_SET_HWP_ERROR(l_rc, RC_HWP_ATTR_UNIT_TEST_FAIL); - FAPI_ERR("hwpTestAttributes: ATTR_SCRATCH_UINT8_1. GET returned %d", - l_uint8); - break; - } - - // Set to zero - l_uint8 = 0; - l_rc = FAPI_ATTR_SET(ATTR_SCRATCH_UINT8_1, NULL, l_uint8); - if (l_rc) - { - FAPI_ERR("hwpTestAttributes: ATTR_SCRATCH_UINT8_1. Error from SET (2)"); - break; - } - } - - //---------------------------------------------------------------------- - // Test ATTR_SCRATCH_UINT8_2 - //---------------------------------------------------------------------- - { - uint8_t l_uint8 = 6; - - // Test set - l_rc = FAPI_ATTR_SET(ATTR_SCRATCH_UINT8_2, NULL, l_uint8); - if (l_rc) - { - FAPI_ERR("hwpTestAttributes: ATTR_SCRATCH_UINT8_2. Error from SET"); - break; - } - - // Test get - l_uint8 = 8; - l_rc = FAPI_ATTR_GET(ATTR_SCRATCH_UINT8_2, NULL, l_uint8); - if (l_rc) - { - FAPI_ERR("hwpTestAttributes: ATTR_SCRATCH_UINT8_2. Error from GET"); - break; - } - - // Check value - if (l_uint8 != 6) - { - FAPI_SET_HWP_ERROR(l_rc, RC_HWP_ATTR_UNIT_TEST_FAIL); - FAPI_ERR("hwpTestAttributes: ATTR_SCRATCH_UINT8_2. GET returned %d", - l_uint8); - break; - } - - // Set to zero - l_uint8 = 0; - l_rc = FAPI_ATTR_SET(ATTR_SCRATCH_UINT8_2, NULL, l_uint8); - if (l_rc) - { - FAPI_ERR("hwpTestAttributes: ATTR_SCRATCH_UINT8_2. Error from SET (2)"); - break; - } - } - - //---------------------------------------------------------------------- - // Test ATTR_SCRATCH_UINT32_1 - //---------------------------------------------------------------------- - { - uint32_t l_uint32 = 5; - - // Test set - l_rc = FAPI_ATTR_SET(ATTR_SCRATCH_UINT32_1, NULL, l_uint32); - if (l_rc) - { - FAPI_ERR("hwpTestAttributes: ATTR_SCRATCH_UINT32_1. Error from SET"); - break; - } - - // Test get - l_uint32 = 8; - l_rc = FAPI_ATTR_GET(ATTR_SCRATCH_UINT32_1, NULL, l_uint32); - if (l_rc) - { - FAPI_ERR("hwpTestAttributes: ATTR_SCRATCH_UINT32_1. Error from GET"); - break; - } - - // Check value - if (l_uint32 != 5) - { - FAPI_SET_HWP_ERROR(l_rc, RC_HWP_ATTR_UNIT_TEST_FAIL); - FAPI_ERR("hwpTestAttributes: ATTR_SCRATCH_UINT32_1. GET returned %d", - l_uint32); - break; - } - - // Set to zero - l_uint32 = 0; - l_rc = FAPI_ATTR_SET(ATTR_SCRATCH_UINT32_1, NULL, l_uint32); - if (l_rc) - { - FAPI_ERR("hwpTestAttributes: ATTR_SCRATCH_UINT32_1. Error from SET (2)"); - break; - } - } - - //---------------------------------------------------------------------- - // Test ATTR_SCRATCH_UINT32_2 - //---------------------------------------------------------------------- - { - uint32_t l_uint32 = 4; - - // Test set - l_rc = FAPI_ATTR_SET(ATTR_SCRATCH_UINT32_2, NULL, l_uint32); - if (l_rc) - { - FAPI_ERR("hwpTestAttributes: ATTR_SCRATCH_UINT32_2. Error from SET"); - break; - } - - // Test get - l_uint32 = 8; - l_rc = FAPI_ATTR_GET(ATTR_SCRATCH_UINT32_2, NULL, l_uint32); - if (l_rc) - { - FAPI_ERR("hwpTestAttributes: ATTR_SCRATCH_UINT32_2. Error from GET"); - break; - } - - // Check value - if (l_uint32 != 4) - { - FAPI_SET_HWP_ERROR(l_rc, RC_HWP_ATTR_UNIT_TEST_FAIL); - FAPI_ERR("hwpTestAttributes: ATTR_SCRATCH_UINT32_2. GET returned %d", - l_uint32); - break; - } - - // Set to zero - l_uint32 = 0; - l_rc = FAPI_ATTR_SET(ATTR_SCRATCH_UINT32_2, NULL, l_uint32); - if (l_rc) - { - FAPI_ERR("hwpTestAttributes: ATTR_SCRATCH_UINT32_2. Error from SET (2)"); - break; - } - } - - //---------------------------------------------------------------------- - // Test ATTR_SCRATCH_UINT64_1 - //---------------------------------------------------------------------- - { - uint64_t l_uint64 = 3; - - // Test set - l_rc = FAPI_ATTR_SET(ATTR_SCRATCH_UINT64_1, NULL, l_uint64); - if (l_rc) - { - FAPI_ERR("hwpTestAttributes: ATTR_SCRATCH_UINT64_1. Error from SET"); - break; - } - - // Test get - l_uint64 = 8; - l_rc = FAPI_ATTR_GET(ATTR_SCRATCH_UINT64_1, NULL, l_uint64); - if (l_rc) - { - FAPI_ERR("hwpTestAttributes: ATTR_SCRATCH_UINT64_1. Error from GET"); - break; - } - - // Check value - if (l_uint64 != 3) - { - FAPI_SET_HWP_ERROR(l_rc, RC_HWP_ATTR_UNIT_TEST_FAIL); - FAPI_ERR("hwpTestAttributes: ATTR_SCRATCH_UINT64_1. GET returned %d", - static_cast<uint32_t>(l_uint64)); - break; - } - - // Set to zero - l_uint64 = 0; - l_rc = FAPI_ATTR_SET(ATTR_SCRATCH_UINT64_1, NULL, l_uint64); - if (l_rc) - { - FAPI_ERR("hwpTestAttributes: ATTR_SCRATCH_UINT64_1. Error from SET (2)"); - break; - } - } - - //---------------------------------------------------------------------- - // Test ATTR_SCRATCH_UINT64_2 - //---------------------------------------------------------------------- - { - uint64_t l_uint64 = 2; - - // Test set - l_rc = FAPI_ATTR_SET(ATTR_SCRATCH_UINT64_2, NULL, l_uint64); - if (l_rc) - { - FAPI_ERR("hwpTestAttributes: ATTR_SCRATCH_UINT64_2. Error from SET"); - break; - } - - // Test get - l_uint64 = 8; - l_rc = FAPI_ATTR_GET(ATTR_SCRATCH_UINT64_2, NULL, l_uint64); - if (l_rc) - { - FAPI_ERR("hwpTestAttributes: ATTR_SCRATCH_UINT64_2. Error from GET"); - break; - } - - // Check value - if (l_uint64 != 2) - { - FAPI_SET_HWP_ERROR(l_rc, RC_HWP_ATTR_UNIT_TEST_FAIL); - FAPI_ERR("hwpTestAttributes: ATTR_SCRATCH_UINT64_2. GET returned %d", - static_cast<uint32_t>(l_uint64)); - break; - } - - // Set to zero - l_uint64 = 0; - l_rc = FAPI_ATTR_SET(ATTR_SCRATCH_UINT64_2, NULL, l_uint64); - if (l_rc) - { - FAPI_ERR("hwpTestAttributes: ATTR_SCRATCH_UINT64_2. Error from SET (2)"); - break; - } - } - - //---------------------------------------------------------------------- - // Test ATTR_SCRATCH_UINT8_ARRAY_1 - //---------------------------------------------------------------------- - { - uint8_t l_uint8array1[32]; - - // Test set - for (uint32_t i = 0; i < 32; i++) - { - l_uint8array1[i] = i + 1; - } - - l_rc = FAPI_ATTR_SET(ATTR_SCRATCH_UINT8_ARRAY_1, NULL, l_uint8array1); - if (l_rc) - { - FAPI_ERR("hwpTestAttributes: ATTR_SCRATCH_UINT8_ARRAY_1. Error from SET"); - break; - } - - // Test get - for (uint32_t i = 0; i < 32; i++) - { - l_uint8array1[i] = 0; - } - - l_rc = FAPI_ATTR_GET(ATTR_SCRATCH_UINT8_ARRAY_1, NULL, l_uint8array1); - if (l_rc) - { - FAPI_ERR("hwpTestAttributes: ATTR_SCRATCH_UINT8_ARRAY_1. Error from GET"); - break; - } - - // Check value - for (uint32_t i = 0; i < 32; i++) - { - if (l_uint8array1[i] != (i + 1)) - { - FAPI_SET_HWP_ERROR(l_rc, RC_HWP_ATTR_UNIT_TEST_FAIL); - FAPI_ERR("hwpTestAttributes: ATTR_SCRATCH_UINT8_ARRAY_1. GET [%d] returned %d", - i, l_uint8array1[i]); - break; - } - } - - if (l_rc) - { - break; - } - - // Set to zero - for (uint32_t i = 0; i < 32; i++) - { - l_uint8array1[i] = 0; - } - - l_rc = FAPI_ATTR_SET(ATTR_SCRATCH_UINT8_ARRAY_1, NULL, l_uint8array1); - if (l_rc) - { - FAPI_ERR("hwpTestAttributes: ATTR_SCRATCH_UINT8_ARRAY_1. Error from SET (2)"); - break; - } - } - - //---------------------------------------------------------------------- - // Test ATTR_SCRATCH_UINT8_ARRAY_2 - //---------------------------------------------------------------------- - { - uint8_t l_uint8 = 1; - uint8_t l_uint8array2[2][3][4]; - - // Test set - l_uint8 = 1; - for (uint32_t i = 0; i < 2; i++) - { - for (uint32_t j = 0; j < 3; j++) - { - for (uint32_t k = 0; k < 4; k++) - { - l_uint8array2[i][j][k] = l_uint8++; - } - } - } - - l_rc = FAPI_ATTR_SET(ATTR_SCRATCH_UINT8_ARRAY_2, NULL, l_uint8array2); - if (l_rc) - { - FAPI_ERR("hwpTestAttributes: ATTR_SCRATCH_UINT8_ARRAY_2. Error from SET"); - break; - } - - // Test get - for (uint32_t i = 0; i < 2; i++) - { - for (uint32_t j = 0; j < 3; j++) - { - for (uint32_t k = 0; k < 4; k++) - { - l_uint8array2[i][j][k] = 0; - } - } - } - - l_rc = FAPI_ATTR_GET(ATTR_SCRATCH_UINT8_ARRAY_2, NULL, l_uint8array2); - if (l_rc) - { - FAPI_ERR("hwpTestAttributes: ATTR_SCRATCH_UINT8_ARRAY_2. Error from GET"); - break; - } - - // Check value - l_uint8 = 1; - for (uint32_t i = 0; i < 2; i++) - { - for (uint32_t j = 0; j < 3; j++) - { - for (uint32_t k = 0; k < 4; k++) - { - if (l_uint8array2[i][j][k] != l_uint8++) - { - FAPI_SET_HWP_ERROR(l_rc, RC_HWP_ATTR_UNIT_TEST_FAIL); - FAPI_ERR("hwpTestAttributes: ATTR_SCRATCH_UINT8_ARRAY_2. GET [%d:%d:%d] returned %d", - i, j, k, l_uint8array2[i][j][k]); - break; - } - } - if (l_rc) - { - break; - } - } - if (l_rc) - { - break; - } - } - - if (l_rc) - { - break; - } - - // Set to zero - for (uint32_t i = 0; i < 2; i++) - { - for (uint32_t j = 0; j < 3; j++) - { - for (uint32_t k = 0; k < 4; k++) - { - l_uint8array2[i][j][k] = 0; - } - } - } - - l_rc = FAPI_ATTR_SET(ATTR_SCRATCH_UINT8_ARRAY_2, NULL, l_uint8array2); - if (l_rc) - { - FAPI_ERR("hwpTestAttributes: ATTR_SCRATCH_UINT8_ARRAY_2. Error from SET (2)"); - break; - } - } - - //---------------------------------------------------------------------- - // Test ATTR_SCRATCH_UINT32_ARRAY_1 - //---------------------------------------------------------------------- - { - uint32_t l_uint32array1[8]; - - // Test set - for (uint32_t i = 0; i < 8; i++) - { - l_uint32array1[i] = i + 1; - } - - l_rc = FAPI_ATTR_SET(ATTR_SCRATCH_UINT32_ARRAY_1, NULL, l_uint32array1); - if (l_rc) - { - FAPI_ERR("hwpTestAttributes: ATTR_SCRATCH_UINT32_ARRAY_1. Error from SET"); - break; - } - - // Test get - for (uint32_t i = 0; i < 8; i++) - { - l_uint32array1[i] = 0; - } - - l_rc = FAPI_ATTR_GET(ATTR_SCRATCH_UINT32_ARRAY_1, NULL, l_uint32array1); - if (l_rc) - { - FAPI_ERR("hwpTestAttributes: ATTR_SCRATCH_UINT32_ARRAY_1. Error from GET"); - break; - } - - // Check value - for (uint32_t i = 0; i < 8; i++) - { - if (l_uint32array1[i] != (i + 1)) - { - FAPI_SET_HWP_ERROR(l_rc, RC_HWP_ATTR_UNIT_TEST_FAIL); - FAPI_ERR("hwpTestAttributes: ATTR_SCRATCH_UINT32_ARRAY_1. GET [%d] returned %d", - i, l_uint32array1[i]); - break; - } - } - - if (l_rc) - { - break; - } - - // Set to zero - for (uint32_t i = 0; i < 8; i++) - { - l_uint32array1[i] = 0; - } - - l_rc = FAPI_ATTR_SET(ATTR_SCRATCH_UINT32_ARRAY_1, NULL, l_uint32array1); - if (l_rc) - { - FAPI_ERR("hwpTestAttributes: ATTR_SCRATCH_UINT32_ARRAY_1. Error from SET (2)"); - break; - } - } - - //---------------------------------------------------------------------- - // Test ATTR_SCRATCH_UINT32_ARRAY_2 - //---------------------------------------------------------------------- - { - uint32_t l_uint32 = 1; - uint32_t l_uint32array2[2][3]; - - // Test set - l_uint32 = 1; - for (uint32_t i = 0; i < 2; i++) - { - for (uint32_t j = 0; j < 3; j++) - { - l_uint32array2[i][j] = l_uint32++; - } - } - - l_rc = FAPI_ATTR_SET(ATTR_SCRATCH_UINT32_ARRAY_2, NULL, l_uint32array2); - if (l_rc) - { - FAPI_ERR("hwpTestAttributes: ATTR_SCRATCH_UINT32_ARRAY_2. Error from SET"); - break; - } - - // Test get - for (uint32_t i = 0; i < 2; i++) - { - for (uint32_t j = 0; j < 3; j++) - { - l_uint32array2[i][j] = 0; - } - } - - l_rc = FAPI_ATTR_GET(ATTR_SCRATCH_UINT32_ARRAY_2, NULL, l_uint32array2); - if (l_rc) - { - FAPI_ERR("hwpTestAttributes: ATTR_SCRATCH_UINT32_ARRAY_2. Error from GET"); - break; - } - - // Check value - l_uint32 = 1; - for (uint32_t i = 0; i < 2; i++) - { - for (uint32_t j = 0; j < 3; j++) - { - if (l_uint32array2[i][j] != l_uint32++) - { - FAPI_SET_HWP_ERROR(l_rc, RC_HWP_ATTR_UNIT_TEST_FAIL); - FAPI_ERR("hwpTestAttributes: ATTR_SCRATCH_UINT32_ARRAY_2. GET [%d:%d] returned %d", - i, j, l_uint32array2[i][j]); - break; - } - } - if (l_rc) - { - break; - } - } - - if (l_rc) - { - break; - } - - // Set to zero - for (uint32_t i = 0; i < 2; i++) - { - for (uint32_t j = 0; j < 3; j++) - { - l_uint32array2[i][j]= 0; - } - } - - l_rc = FAPI_ATTR_SET(ATTR_SCRATCH_UINT32_ARRAY_2, NULL, l_uint32array2); - if (l_rc) - { - FAPI_ERR("hwpTestAttributes: ATTR_SCRATCH_UINT32_ARRAY_2. Error from SET (2)"); - break; - } - } - - //---------------------------------------------------------------------- - // Test ATTR_SCRATCH_UINT64_ARRAY_1 - //---------------------------------------------------------------------- - { - // Demonstrate the use of a heap based array - uint64_t (&l_uint64array1)[4] = *(reinterpret_cast<uint64_t(*)[4]>(new uint64_t[4])); - - // Test set - for (uint32_t i = 0; i < 4; i++) - { - l_uint64array1[i] = i + 1; - } - - l_rc = FAPI_ATTR_SET(ATTR_SCRATCH_UINT64_ARRAY_1, NULL, l_uint64array1); - if (l_rc) - { - FAPI_ERR("hwpTestAttributes: ATTR_SCRATCH_UINT64_ARRAY_1. Error from SET"); - break; - } - - // Test get - for (uint32_t i = 0; i < 4; i++) - { - l_uint64array1[i] = 0; - } - - l_rc = FAPI_ATTR_GET(ATTR_SCRATCH_UINT64_ARRAY_1, NULL, l_uint64array1); - if (l_rc) - { - FAPI_ERR("hwpTestAttributes: ATTR_SCRATCH_UINT64_ARRAY_1. Error from GET"); - break; - } - - // Check value - for (uint32_t i = 0; i < 4; i++) - { - if (l_uint64array1[i] != (i + 1)) - { - FAPI_SET_HWP_ERROR(l_rc, RC_HWP_ATTR_UNIT_TEST_FAIL); - FAPI_ERR("hwpTestAttributes: ATTR_SCRATCH_UINT64_ARRAY_1. GET [%d] returned %d", - i, static_cast<uint32_t>(l_uint64array1[i])); - break; - } - } - - if (l_rc) - { - break; - } - - // Set to zero - for (uint32_t i = 0; i < 4; i++) - { - l_uint64array1[i] = 0; - } - - l_rc = FAPI_ATTR_SET(ATTR_SCRATCH_UINT64_ARRAY_1, NULL, l_uint64array1); - if (l_rc) - { - FAPI_ERR("hwpTestAttributes: ATTR_SCRATCH_UINT64_ARRAY_1. Error from SET (2)"); - break; - } - - delete [] &l_uint64array1; - } - - //---------------------------------------------------------------------- - // Test ATTR_SCRATCH_UINT64_ARRAY_2 - //---------------------------------------------------------------------- - { - uint64_t l_uint64 = 1; - uint64_t l_uint64array2[2][2]; - - // Test set - l_uint64 = 1; - for (uint32_t i = 0; i < 2; i++) - { - for (uint32_t j = 0; j < 2; j++) - { - l_uint64array2[i][j] = l_uint64++; - } - } - - l_rc = FAPI_ATTR_SET(ATTR_SCRATCH_UINT64_ARRAY_2, NULL, l_uint64array2); - if (l_rc) - { - FAPI_ERR("hwpTestAttributes: ATTR_SCRATCH_UINT64_ARRAY_2. Error from SET"); - break; - } - - // Test get - for (uint32_t i = 0; i < 2; i++) - { - for (uint32_t j = 0; j < 2; j++) - { - l_uint64array2[i][j] = 0; - } - } - - l_rc = FAPI_ATTR_GET(ATTR_SCRATCH_UINT64_ARRAY_2, NULL, l_uint64array2); - if (l_rc) - { - FAPI_ERR("hwpTestAttributes: ATTR_SCRATCH_UINT64_ARRAY_2. Error from GET"); - break; - } - - // Check value - l_uint64 = 1; - for (uint32_t i = 0; i < 2; i++) - { - for (uint32_t j = 0; j < 2; j++) - { - if (l_uint64array2[i][j] != l_uint64++) - { - FAPI_SET_HWP_ERROR(l_rc, RC_HWP_ATTR_UNIT_TEST_FAIL); - FAPI_ERR("hwpTestAttributes: ATTR_SCRATCH_UINT64_ARRAY_2. GET [%d:%d] returned %d", - i, j, static_cast<uint32_t>(l_uint64array2[i][j])); - break; - } - } - if (l_rc) - { - break; - } - } - - if (l_rc) - { - break; - } - - // Set to zero - for (uint32_t i = 0; i < 2; i++) - { - for (uint32_t j = 0; j < 2; j++) - { - l_uint64array2[i][j]= 0; - } - } - - l_rc = FAPI_ATTR_SET(ATTR_SCRATCH_UINT64_ARRAY_2, NULL, l_uint64array2); - if (l_rc) - { - FAPI_ERR("hwpTestAttributes: ATTR_SCRATCH_UINT64_ARRAY_2. Error from SET (2)"); - break; - } - } - - //---------------------------------------------------------------------- - // Test setting and getting an enum value from a scratch attribute - //---------------------------------------------------------------------- - { - uint64_t l_uint64 = fapi::ENUM_ATTR_SCRATCH_UINT64_2_VAL_C; - - // Test set - l_rc = FAPI_ATTR_SET(ATTR_SCRATCH_UINT64_2, NULL, l_uint64); - if (l_rc) - { - FAPI_ERR("hwpTestAttributes: ATTR_SCRATCH_UINT64_2. Error from SET (enum)"); - break; - } - - // Test get - l_uint64 = 0; - l_rc = FAPI_ATTR_GET(ATTR_SCRATCH_UINT64_2, NULL, l_uint64); - if (l_rc) - { - FAPI_ERR("hwpTestAttributes: ATTR_SCRATCH_UINT64_2. Error from GET (enum)"); - break; - } - - // Check value - if (l_uint64 != fapi::ENUM_ATTR_SCRATCH_UINT64_2_VAL_C) - { - FAPI_SET_HWP_ERROR(l_rc, RC_HWP_ATTR_UNIT_TEST_FAIL); - FAPI_ERR("hwpTestAttributes: ATTR_SCRATCH_UINT64_2. GET returned %d (enum)", - static_cast<uint32_t>(l_uint64)); - break; - } - - // Set to zero - l_uint64 = 0; - l_rc = FAPI_ATTR_SET(ATTR_SCRATCH_UINT64_2, NULL, l_uint64); - if (l_rc) - { - FAPI_ERR("hwpTestAttributes: ATTR_SCRATCH_UINT64_2. Error from SET (enum2)"); - break; - } - } - - //---------------------------------------------------------------------- - // Removed getting scratch attributes using fapiGetInitFileAttr(). This - // now only supports the getting of attributes that are actually used by - // initfiles and those are excercised by the test initfile - //---------------------------------------------------------------------- - - //---------------------------------------------------------------------- - // Test getting an invalid attribute using fapiGetInitFileAttr() - //---------------------------------------------------------------------- - uint64_t l_val = 0; - fapi::AttributeId l_badId = static_cast<fapi::AttributeId>(0xff); - l_rc = fapiGetInitFileAttr(l_badId, NULL, l_val); - - if (l_rc) - { - // Delete the error rather than logging it to avoid it getting - // interpreted as a real problem - FAPI_INF("hwpTestAttributes: Deleting expected error 0x%x from fapiGetInitFileAttr", - static_cast<uint32_t>(l_rc)); - l_rc = fapi::FAPI_RC_SUCCESS; - } - else - { - FAPI_SET_HWP_ERROR(l_rc, RC_HWP_ATTR_UNIT_TEST_FAIL); - FAPI_ERR("hwpTestAttributes: Did not get error from fapiGetInitFileAttr"); - break; - } - - //---------------------------------------------------------------------- - // Test invalid accesses - //---------------------------------------------------------------------- - - // All of the following should not compile due to wrong types used - { - //uint32_t l_val; - //l_rc = FAPI_ATTR_GET(ATTR_SCRATCH_UINT8_1, NULL, l_val); - //l_rc = FAPI_ATTR_SET(ATTR_SCRATCH_UINT8_1, NULL, l_val); - } - { - //uint64_t l_val; - //l_rc = FAPI_ATTR_GET(ATTR_SCRATCH_UINT32_1, NULL, l_val); - //l_rc = FAPI_ATTR_SET(ATTR_SCRATCH_UINT32_1, NULL, l_val); - } - { - //uint8_t l_val; - //l_rc = FAPI_ATTR_GET(ATTR_SCRATCH_UINT64_1, NULL, l_val); - //l_rc = FAPI_ATTR_SET(ATTR_SCRATCH_UINT64_1, NULL, l_val); - } - { - //uint8_t l_array[33]; // size should be 32 - //l_rc = FAPI_ATTR_GET(ATTR_SCRATCH_UINT8_ARRAY_1, NULL, l_array); - //l_rc = FAPI_ATTR_SET(ATTR_SCRATCH_UINT8_ARRAY_1, NULL, l_array); - } - { - //uint8_t l_array[2][3]; // type should be uint32_t - //l_rc = FAPI_ATTR_GET(ATTR_SCRATCH_UINT32_ARRAY_2, NULL, l_array); - //l_rc = FAPI_ATTR_SET(ATTR_SCRATCH_UINT32_ARRAY_2, NULL, l_array); - } - { - //uint64_t l_array[2][1]; // second dimension should be 2 - //l_rc = FAPI_ATTR_GET(ATTR_SCRATCH_UINT64_ARRAY_2, NULL, l_array); - //l_rc = FAPI_ATTR_SET(ATTR_SCRATCH_UINT64_ARRAY_2, NULL, l_array); - } - - //---------------------------------------------------------------------- - // Test AttributeTank functions with empty tank - //---------------------------------------------------------------------- - { - // Create a local OverrideAttributeTank (this is not the singleton) - fapi::OverrideAttributeTank l_tank; - - // Check that tank is empty - if (l_tank.attributesExist()) - { - FAPI_SET_HWP_ERROR(l_rc, RC_HWP_ATTR_UNIT_TEST_FAIL); - FAPI_ERR("hwpTestAttributes: Error. AttributeTank is not empty (1.1)"); - break; - } - - // Clear all attributes from empty tank - l_tank.clearAllAttributes(); - - // Clear a non-const system attribute from empty tank - l_tank.clearNonConstAttribute(fapi::ATTR_SCRATCH_UINT64_1, NULL); - - // Try to get a system attribute from empty tank - uint64_t l_val = 0; - if (l_tank.getAttribute(fapi::ATTR_SCRATCH_UINT64_1, NULL, l_val)) - { - FAPI_SET_HWP_ERROR(l_rc, RC_HWP_ATTR_UNIT_TEST_FAIL); - FAPI_ERR("hwpTestAttributes: Error. Got sys attr from empty tank (1.2)"); - break; - } - - // Try to get a chiplet attribute from empty tank - if (l_tank.getAttribute(fapi::ATTR_SCRATCH_UINT64_1, &i_mbaTarget, - l_val)) - { - FAPI_SET_HWP_ERROR(l_rc, RC_HWP_ATTR_UNIT_TEST_FAIL); - FAPI_ERR("hwpTestAttributes: Error. Got chiplet attr from empty tank (1.3)"); - break; - } - - // Try to get all attributes from empty tank - std::vector<fapi::AttributeChunk> l_attributes; - l_tank.getAllAttributes(fapi::AttributeTank::ALLOC_TYPE_MALLOC, - l_attributes); - - if (l_attributes.size()) - { - FAPI_SET_HWP_ERROR(l_rc, RC_HWP_ATTR_UNIT_TEST_FAIL); - FAPI_ERR("hwpTestAttributes: Error. Got all attrs from empty tank (1.4)"); - break; - } - } - - //---------------------------------------------------------------------- - // Test AttributeTank functions with single attribute in tank - //---------------------------------------------------------------------- - { - // Create a local OverrideAttributeTank (this is not the singleton) - fapi::OverrideAttributeTank l_tank; - - // Add ATTR_SCRATCH_UINT64_1 as a sytem attribute to the tank - uint64_t l_val = 4; - l_tank.setAttribute(fapi::ATTR_SCRATCH_UINT64_1, NULL, l_val); - - // Check that attributes exist in the tank - if (!l_tank.attributesExist()) - { - FAPI_SET_HWP_ERROR(l_rc, RC_HWP_ATTR_UNIT_TEST_FAIL); - FAPI_ERR("hwpTestAttributes: Error. AttributeTank is empty (2.1)"); - break; - } - - // Try to get the wrong attribute from the tank - l_val = 0; - if (l_tank.getAttribute(fapi::ATTR_SCRATCH_UINT64_2, NULL, l_val)) - { - FAPI_SET_HWP_ERROR(l_rc, RC_HWP_ATTR_UNIT_TEST_FAIL); - FAPI_ERR("hwpTestAttributes: Error. Got wrong attr from tank (2.2)"); - break; - } - - // Get the attribute from the tank - if (!(l_tank.getAttribute(fapi::ATTR_SCRATCH_UINT64_1, NULL, l_val))) - { - FAPI_SET_HWP_ERROR(l_rc, RC_HWP_ATTR_UNIT_TEST_FAIL); - FAPI_ERR("hwpTestAttributes: Error. Did not get attr from tank (2.3)"); - break; - } - - if (l_val != 4) - { - FAPI_SET_HWP_ERROR(l_rc, RC_HWP_ATTR_UNIT_TEST_FAIL); - FAPI_ERR("hwpTestAttributes: Error. Got bad value (0x%llx) from tank (2.4)", - l_val); - break; - } - - // Get all attributes from the tank - std::vector<fapi::AttributeChunk> l_attributes; - l_tank.getAllAttributes(fapi::AttributeTank::ALLOC_TYPE_NEW, - l_attributes); - - if (l_attributes.size() != 1) - { - FAPI_SET_HWP_ERROR(l_rc, RC_HWP_ATTR_UNIT_TEST_FAIL); - FAPI_ERR("hwpTestAttributes: Error. Got wrong chunk size (%d) of attrs from tank (2.5)", - l_attributes.size()); - break; - } - - if (l_attributes[0].iv_numAttributes != 1) - { - FAPI_SET_HWP_ERROR(l_rc, RC_HWP_ATTR_UNIT_TEST_FAIL); - FAPI_ERR("hwpTestAttributes: Error. Got wrong size (%d) of attrs from tank (2.6)", - l_attributes[0].iv_numAttributes); - break; - } - - fapi::Attribute * l_pAttr = reinterpret_cast<fapi::Attribute *> - (l_attributes[0].iv_pAttributes); - if (l_pAttr[0].iv_val != 4) - { - FAPI_SET_HWP_ERROR(l_rc, RC_HWP_ATTR_UNIT_TEST_FAIL); - FAPI_ERR("hwpTestAttributes: Error. Got bad value (0x%016llx) from tank (2.7)", - l_pAttr[0].iv_val); - break; - } - delete [] l_attributes[0].iv_pAttributes; - l_attributes[0].iv_pAttributes = NULL; - } - - //---------------------------------------------------------------------- - // Test AttributeTank functions with multiple attributes in tank - //---------------------------------------------------------------------- - { - // Create a local OverrideAttributeTank (this is not the singleton) - fapi::OverrideAttributeTank l_tank; - - // Add ATTR_SCRATCH_UINT64_1 as a chip attribute to the tank - uint64_t l_val = 4; - l_tank.setAttribute(fapi::ATTR_SCRATCH_UINT64_1, &i_procTarget, l_val); - - // Add ATTR_SCRATCH_UINT64_2 as an MBA attribute to the tank - l_val = 5; - l_tank.setAttribute(fapi::ATTR_SCRATCH_UINT64_2, &i_mbaTarget, l_val); - - // Get the first attribute from the tank - if (!(l_tank.getAttribute(fapi::ATTR_SCRATCH_UINT64_1, &i_procTarget, l_val))) - { - FAPI_SET_HWP_ERROR(l_rc, RC_HWP_ATTR_UNIT_TEST_FAIL); - FAPI_ERR("hwpTestAttributes: Error. Did not get attr from tank (3.1)"); - break; - } - - if (l_val != 4) - { - FAPI_SET_HWP_ERROR(l_rc, RC_HWP_ATTR_UNIT_TEST_FAIL); - FAPI_ERR("hwpTestAttributes: Error. Got bad value (0x%016llx) from tank (3.2)", - l_val); - break; - } - - // Get the second attribute from the tank - if (!(l_tank.getAttribute(fapi::ATTR_SCRATCH_UINT64_2, &i_mbaTarget, l_val))) - { - FAPI_SET_HWP_ERROR(l_rc, RC_HWP_ATTR_UNIT_TEST_FAIL); - FAPI_ERR("hwpTestAttributes: Error. Did not get attr from tank (3.3)"); - break; - } - - if (l_val != 5) - { - FAPI_SET_HWP_ERROR(l_rc, RC_HWP_ATTR_UNIT_TEST_FAIL); - FAPI_ERR("hwpTestAttributes: Error. Got bad value (0x%llx) from tank (3.4)", - l_val); - break; - } - - // Get all attributes from the tank - std::vector<fapi::AttributeChunk> l_attributes; - l_tank.getAllAttributes(fapi::AttributeTank::ALLOC_TYPE_MALLOC, - l_attributes); - - if (l_attributes.size() != 1) - { - FAPI_SET_HWP_ERROR(l_rc, RC_HWP_ATTR_UNIT_TEST_FAIL); - FAPI_ERR("hwpTestAttributes: Error. Got wrong chunk size (%d) of attrs from tank (3.5)", - l_attributes.size()); - break; - } - - if (l_attributes[0].iv_numAttributes != 2) - { - FAPI_SET_HWP_ERROR(l_rc, RC_HWP_ATTR_UNIT_TEST_FAIL); - FAPI_ERR("hwpTestAttributes: Error. Got wrong size (%d) of attrs from tank (3.6)", - l_attributes[0].iv_numAttributes); - break; - } - - fapi::Attribute * l_pAttr = reinterpret_cast<fapi::Attribute *> - (l_attributes[0].iv_pAttributes); - if (l_pAttr[0].iv_val != 4) - { - FAPI_SET_HWP_ERROR(l_rc, RC_HWP_ATTR_UNIT_TEST_FAIL); - FAPI_ERR("hwpTestAttributes: Error. Got bad value (0x%llx) from tank (3.7)", - l_pAttr[0].iv_val); - break; - } - - if (l_pAttr[1].iv_val != 5) - { - FAPI_SET_HWP_ERROR(l_rc, RC_HWP_ATTR_UNIT_TEST_FAIL); - FAPI_ERR("hwpTestAttributes: Error. Got bad value (0x%llx) from tank (3.8)", - l_pAttr->iv_val); - break; - } - - free (l_attributes[0].iv_pAttributes); - l_attributes[0].iv_pAttributes = NULL; - } - - //---------------------------------------------------------------------- - // Test AttributeTank functions with constant attribute - //---------------------------------------------------------------------- - { - // Create a local OverrideAttributeTank (this is not the singleton) - fapi::OverrideAttributeTank l_tank; - - // Set const attribute - fapi::Attribute l_attr; - l_attr.iv_val = 7; - l_attr.iv_attrId = fapi::ATTR_SCRATCH_UINT64_2; - l_attr.iv_targetType = fapi::TARGET_TYPE_SYSTEM; - l_attr.iv_pos = fapi::ATTR_POS_NA; - l_attr.iv_unitPos = fapi::ATTR_UNIT_POS_NA; - l_attr.iv_flags = fapi::ATTR_FLAG_CONST; - l_attr.iv_arrayD1 = 0; - l_attr.iv_arrayD2 = 0; - l_attr.iv_arrayD3 = 0; - l_attr.iv_arrayD4 = 0; - l_tank.setAttribute(l_attr); - - // Try to clear the attribute, it should not be cleared - l_tank.clearNonConstAttribute(fapi::ATTR_SCRATCH_UINT64_2, NULL); - - // Check that tank is not-empty - if (!l_tank.attributesExist()) - { - FAPI_SET_HWP_ERROR(l_rc, RC_HWP_ATTR_UNIT_TEST_FAIL); - FAPI_ERR("hwpTestAttributes: Error. AttributeTank is empty (4.1)"); - break; - } - - // Clear all attribute - l_tank.clearAllAttributes(); - - // Check that tank is empty - if (l_tank.attributesExist()) - { - FAPI_SET_HWP_ERROR(l_rc, RC_HWP_ATTR_UNIT_TEST_FAIL); - FAPI_ERR("hwpTestAttributes: Error. AttributeTank is not empty (4.2)"); - break; - } - } - - //---------------------------------------------------------------------- - // Test adding the same attribute twice to a tank - //---------------------------------------------------------------------- - { - // Create a local OverrideAttributeTank (this is not the singleton) - fapi::OverrideAttributeTank l_tank; - - // Add ATTR_SCRATCH_UINT64_1 to the tank twice - uint64_t l_val = 4; - l_tank.setAttribute(fapi::ATTR_SCRATCH_UINT64_1, NULL, l_val); - l_val = 5; - l_tank.setAttribute(fapi::ATTR_SCRATCH_UINT64_1, NULL, l_val); - - // Get all attributes from the tank - std::vector<fapi::AttributeChunk> l_attributes; - l_tank.getAllAttributes(fapi::AttributeTank::ALLOC_TYPE_MALLOC, - l_attributes); - - if (l_attributes.size() != 1) - { - FAPI_SET_HWP_ERROR(l_rc, RC_HWP_ATTR_UNIT_TEST_FAIL); - FAPI_ERR("hwpTestAttributes: Error. Got wrong chunk size (%d) of attrs from tank (5.1)", - l_attributes.size()); - break; - } - - if (l_attributes[0].iv_numAttributes != 1) - { - FAPI_SET_HWP_ERROR(l_rc, RC_HWP_ATTR_UNIT_TEST_FAIL); - FAPI_ERR("hwpTestAttributes: Error. Got wrong size (%d) of attrs from tank (5.2)", - l_attributes[0].iv_numAttributes); - break; - } - - fapi::Attribute * l_pAttr = reinterpret_cast<fapi::Attribute *> - (l_attributes[0].iv_pAttributes); - if (l_pAttr[0].iv_val != 5) - { - FAPI_SET_HWP_ERROR(l_rc, RC_HWP_ATTR_UNIT_TEST_FAIL); - FAPI_ERR("hwpTestAttributes: Error. Got bad value (0x%llx) from tank (5.3)", - l_pAttr[0].iv_val); - break; - } - - free (l_attributes[0].iv_pAttributes); - l_attributes[0].iv_pAttributes = NULL; - } - - } while (0); - - FAPI_INF("hwpTestAttributes: End HWP"); - return l_rc; -} - -} // extern "C" diff --git a/src/usr/hwpf/hwp/makefile b/src/usr/hwpf/hwp/makefile index 2e8d7357e..b0390cb17 100644 --- a/src/usr/hwpf/hwp/makefile +++ b/src/usr/hwpf/hwp/makefile @@ -36,7 +36,6 @@ OBJS = fapiTestHwp.o \ fapiTestHwpError.o \ fapiTestHwpFfdc.o \ fapiTestHwpConfig.o \ - fapiTestHwpAttr.o \ fapiTestHwpDq.o \ fapiHwpExecInitFile.o \ dimmBadDqBitmapFuncs.o \ diff --git a/src/usr/hwpf/makefile b/src/usr/hwpf/makefile index f83583a28..a8ae92228 100644 --- a/src/usr/hwpf/makefile +++ b/src/usr/hwpf/makefile @@ -164,8 +164,8 @@ FAPI_ATTR_ID_TARGET = fapiAttributeIds.H # The FAPI files generated from Attribute XML files FAPI_ATTR_TARGETS = fapiChipEcFeature.C fapiAttributePlatCheck.H \ - fapiAttributesSupported.html fapiAttributeIds.txt \ - fapiAttributeEnums.txt + fapiAttributesSupported.html fapiAttrInfo.csv \ + fapiAttrEnumInfo.csv # The binary, list and attr files generated from Initfiles # Generation depends on ifcompiler and fapiAttributeIds.H diff --git a/src/usr/hwpf/plat/fapiPlatAttrOverrideSync.C b/src/usr/hwpf/plat/fapiPlatAttrOverrideSync.C index baadaec83..4b3989029 100644 --- a/src/usr/hwpf/plat/fapiPlatAttrOverrideSync.C +++ b/src/usr/hwpf/plat/fapiPlatAttrOverrideSync.C @@ -35,13 +35,13 @@ #include <string.h> #include <vector> #include <sys/msg.h> -#include <util/singleton.H> #include <errl/errlentry.H> #include <errl/errlmanager.H> #include <mbox/mboxif.H> -#include <hwpf/fapi/fapiAttributeTank.H> #include <hwpf/plat/fapiPlatAttrOverrideSync.H> #include <hwpf/plat/fapiPlatTrace.H> +#include <targeting/common/utilFilter.H> +#include <targeting/common/attributeTank.H> namespace fapi { @@ -50,23 +50,10 @@ namespace fapi // Global Variables //****************************************************************************** -// Attribute set directly by debug tool in standalone Hostboot mode to apply -// an Attribute Override -fapi::Attribute g_attrOverride; - -namespace attrOverrideSync -{ - -/** - * @brief Attribute Override/Sync Mailbox Message Type Constants - * These must be kept in sync with FSP firmware - */ -enum MAILBOX_MSG_TYPE -{ - MSG_SET_OVERRIDES = MBOX::FIRST_UNSECURE_MSG + 0x10, // FSP<->Hostboot - MSG_CLEAR_ALL_OVERRIDES = MBOX::FIRST_UNSECURE_MSG + 0x11, // FSP<->Hostboot - MSG_SET_SYNC_ATTS = MBOX::FIRST_UNSECURE_MSG + 0x12, // FSP<--Hostboot -}; +// Set by a debug tool to directly apply an Attribute Override +TARGETING::AttributeTank::AttributeHeader g_attrOverrideHeader; +uint8_t g_attrOverride[AttrOverrideSync::MAX_DIRECT_OVERRIDE_ATTR_SIZE_BYTES]; +uint8_t g_attrOverrideFapiTank = 0; //****************************************************************************** // Apply a HWPF Attribute Override written directly into Hostboot memory from @@ -75,19 +62,92 @@ enum MAILBOX_MSG_TYPE void directOverride() { // Apply the attribute override - Singleton<fapi::OverrideAttributeTank>::instance(). - setAttribute(g_attrOverride); + if (g_attrOverrideFapiTank) + { + FAPI_IMP( + "directOverride: Applying direct attr override to FAPI tank (0x%08x:0x%08x:0x%04x:0x%02x)", + g_attrOverrideHeader.iv_attrId, g_attrOverrideHeader.iv_targetType, + g_attrOverrideHeader.iv_pos, g_attrOverrideHeader.iv_unitPos); + + theAttrOverrideSync().iv_overrideTank.setAttribute( + g_attrOverrideHeader.iv_attrId, + g_attrOverrideHeader.iv_targetType, + g_attrOverrideHeader.iv_pos, + g_attrOverrideHeader.iv_unitPos, + g_attrOverrideHeader.iv_flags, + g_attrOverrideHeader.iv_valSize, + &g_attrOverride); + } + else + { + // Convert the FAPI targeting type to TARGETING + TARGETING::TYPE l_targetType = TARGETING::TYPE_SYS; + + switch (g_attrOverrideHeader.iv_targetType) + { + case fapi::TARGET_TYPE_DIMM: + l_targetType = TARGETING::TYPE_DIMM; + break; + case fapi::TARGET_TYPE_PROC_CHIP: + l_targetType = TARGETING::TYPE_PROC; + break; + case fapi::TARGET_TYPE_MEMBUF_CHIP: + l_targetType = TARGETING::TYPE_MEMBUF; + break; + case fapi::TARGET_TYPE_EX_CHIPLET: + l_targetType = TARGETING::TYPE_EX; + break; + case fapi::TARGET_TYPE_MBA_CHIPLET: + l_targetType = TARGETING::TYPE_MBA; + break; + case fapi::TARGET_TYPE_MCS_CHIPLET: + l_targetType = TARGETING::TYPE_MCS; + break; + case fapi::TARGET_TYPE_XBUS_ENDPOINT: + l_targetType = TARGETING::TYPE_XBUS; + break; + case fapi::TARGET_TYPE_ABUS_ENDPOINT: + l_targetType = TARGETING::TYPE_ABUS; + break; + } + + FAPI_IMP( + "directOverride: Applying direct attr override to TARG tank (0x%08x:0x%08x:0x%04x:0x%02x)", + g_attrOverrideHeader.iv_attrId, l_targetType, + g_attrOverrideHeader.iv_pos, g_attrOverrideHeader.iv_unitPos); + + TARGETING::Target::theTargOverrideAttrTank().setAttribute( + g_attrOverrideHeader.iv_attrId, + l_targetType, + g_attrOverrideHeader.iv_pos, + g_attrOverrideHeader.iv_unitPos, + g_attrOverrideHeader.iv_flags, + g_attrOverrideHeader.iv_valSize, + &g_attrOverride); + } } //****************************************************************************** -void monitorForFspMessages() +AttrOverrideSync & theAttrOverrideSync() +{ + return Singleton<AttrOverrideSync>::instance(); +} + +//****************************************************************************** +AttrOverrideSync::AttrOverrideSync() {} + +//****************************************************************************** +AttrOverrideSync::~AttrOverrideSync() {} + +//****************************************************************************** +void AttrOverrideSync::monitorForFspMessages() { FAPI_IMP("monitorForFspMessages starting"); - + // Register a message queue with the mailbox msg_q_t l_pMsgQ = msg_q_create(); errlHndl_t l_pErr = MBOX::msgq_register(MBOX::HB_HWPF_ATTR_MSGQ, l_pMsgQ); - + if (l_pErr) { // In the unlikely event that registering fails, the code will commit an @@ -95,33 +155,41 @@ void monitorForFspMessages() FAPI_ERR("monitorForFspMessages: Error registering msgq with mailbox"); errlCommit(l_pErr, HWPF_COMP_ID); } - + while (1) { msg_t * l_pMsg = msg_wait(l_pMsgQ); - + if (l_pMsg->type == MSG_SET_OVERRIDES) { // FSP is setting attribute override(s). - uint64_t l_size = l_pMsg->data[1]; - FAPI_INF("monitorForFspMessages: MSG_SET_OVERRIDES (%lld overrides)", - l_size / sizeof(fapi::Attribute)); - Attribute * l_pAttribute = - reinterpret_cast<Attribute *>(l_pMsg->extra_data); - - while (l_size >= sizeof(fapi::Attribute)) + uint64_t l_tank = l_pMsg->data[0]; + TARGETING::AttributeTank::AttributeSerializedChunk l_chunk; + l_chunk.iv_size = l_pMsg->data[1]; + l_chunk.iv_pAttributes = static_cast<uint8_t *>(l_pMsg->extra_data); + + if (l_tank == TARGETING::AttributeTank::TANK_LAYER_FAPI) + { + FAPI_INF( + "monitorForFspMessages: MSG_SET_OVERRIDES FAPI (size %lld)", + l_pMsg->data[1]); + iv_overrideTank.deserializeAttributes(l_chunk); + } + else { - Singleton<fapi::OverrideAttributeTank>::instance(). - setAttribute(*l_pAttribute); - l_pAttribute++; - l_size -= sizeof(fapi::Attribute); + FAPI_INF( + "monitorForFspMessages: MSG_SET_OVERRIDES TARG (size %lld)", + l_pMsg->data[1]); + TARGETING::Target::theTargOverrideAttrTank(). + deserializeAttributes(l_chunk); } - + // Free the memory free(l_pMsg->extra_data); l_pMsg->extra_data = NULL; + l_pMsg->data[0] = 0; l_pMsg->data[1] = 0; - + if (msg_is_async(l_pMsg)) { msg_free(l_pMsg); @@ -136,9 +204,9 @@ void monitorForFspMessages() { // FSP is clearing all attribute overrides. FAPI_INF("monitorForFspMessages: MSG_CLEAR_ALL_OVERRIDES"); - Singleton<fapi::OverrideAttributeTank>::instance(). - clearAllAttributes(); - + iv_overrideTank.clearAllAttributes(); + TARGETING::Target::theTargOverrideAttrTank().clearAllAttributes(); + if (msg_is_async(l_pMsg)) { msg_free(l_pMsg); @@ -158,58 +226,68 @@ void monitorForFspMessages() } //****************************************************************************** -// Utility function called by sendAttrOverridesAndSyncsToFsp -//****************************************************************************** -errlHndl_t sendAttrsToFsp(const MAILBOX_MSG_TYPE i_msgType, - std::vector<AttributeChunk> & i_attributes) +errlHndl_t AttrOverrideSync::sendAttrsToFsp( + const MAILBOX_MSG_TYPE i_msgType, + const TARGETING::AttributeTank::TankLayer i_tankLayer, + std::vector<TARGETING::AttributeTank::AttributeSerializedChunk> & + io_attributes) { errlHndl_t l_pErr = NULL; - + + std::vector<TARGETING::AttributeTank::AttributeSerializedChunk>::iterator + l_itr; + // Send Attributes through the mailbox chunk by chunk. - for (size_t i = 0; i < i_attributes.size(); i++) + for (l_itr = io_attributes.begin(); l_itr != io_attributes.end(); ++l_itr) { msg_t * l_pMsg = msg_allocate(); l_pMsg->type = i_msgType; - l_pMsg->data[0] = 0; - l_pMsg->data[1] = i_attributes[i].iv_numAttributes * sizeof(Attribute); - l_pMsg->extra_data = i_attributes[i].iv_pAttributes; - + l_pMsg->data[0] = i_tankLayer; + l_pMsg->data[1] = (*l_itr).iv_size; + l_pMsg->extra_data = (*l_itr).iv_pAttributes; + // Send the message and wait for a response, the response message is not // read, it just ensures that the code waits until the FSP is done // Note: A possible performance boost could be to send only the last // message synchronously to avoid the small delay between each // message l_pErr = MBOX::sendrecv(MBOX::FSP_HWPF_ATTR_MSGQ, l_pMsg); - + if (l_pErr) { FAPI_ERR("sendAttrsToFsp: Error sending to FSP"); msg_free(l_pMsg); + l_pMsg = NULL; break; } - + // Mailbox freed the chunk data - i_attributes[i].iv_pAttributes = NULL; + (*l_itr).iv_pAttributes = NULL; msg_free(l_pMsg); + l_pMsg = NULL; } - + // Free any memory (only in error case will there be memory to free) and // clear the vector of Attribute Chunks - for (size_t i = 0; i < i_attributes.size(); i++) + for (l_itr = io_attributes.begin(); l_itr != io_attributes.end(); ++l_itr) { - free(i_attributes[i].iv_pAttributes); - i_attributes[i].iv_pAttributes = NULL; + free((*l_itr).iv_pAttributes); + (*l_itr).iv_pAttributes = NULL; } - i_attributes.clear(); - + io_attributes.clear(); + return l_pErr; } //****************************************************************************** -void sendAttrOverridesAndSyncsToFsp() +void AttrOverrideSync::sendAttrOverridesAndSyncsToFsp() { + const uint32_t MAILBOX_CHUNK_SIZE = 4096; + if (MBOX::mailbox_enabled()) { + errlHndl_t l_pErr = NULL; + // Clear all current FSP Attribute Overrides msg_t * l_pMsg = msg_allocate(); l_pMsg->type = MSG_CLEAR_ALL_OVERRIDES; @@ -218,11 +296,12 @@ void sendAttrOverridesAndSyncsToFsp() l_pMsg->extra_data = NULL; // Send the message - errlHndl_t l_pErr = MBOX::send(MBOX::FSP_HWPF_ATTR_MSGQ, l_pMsg); - + l_pErr = MBOX::send(MBOX::FSP_HWPF_ATTR_MSGQ, l_pMsg); + if (l_pErr) { - FAPI_ERR("SendAttrOverridesToFsp: Error clearing FSP overrides"); + FAPI_ERR( + "sendAttrOverridesAndSyncsToFsp: Error clearing overrides"); errlCommit(l_pErr, HWPF_COMP_ID); msg_free(l_pMsg); l_pMsg = NULL; @@ -232,46 +311,93 @@ void sendAttrOverridesAndSyncsToFsp() l_pMsg = NULL; // Send Hostboot Attribute Overrides to the FSP - std::vector<AttributeChunk> l_attributes; - - Singleton<fapi::OverrideAttributeTank>::instance(). - getAllAttributes(AttributeTank::ALLOC_TYPE_MALLOC, - l_attributes); - - if (l_attributes.size()) + for (uint32_t i = TARGETING::AttributeTank::TANK_LAYER_FAPI; + i <= TARGETING::AttributeTank::TANK_LAYER_TARG; i++) { - l_pErr = sendAttrsToFsp(MSG_SET_OVERRIDES, l_attributes); + std::vector<TARGETING::AttributeTank::AttributeSerializedChunk> + l_attributes; - if (l_pErr) + if (i == TARGETING::AttributeTank::TANK_LAYER_FAPI) { - FAPI_ERR("SendAttrOverridesToFsp: Error sending overrides to FSP"); - errlCommit(l_pErr, HWPF_COMP_ID); + iv_overrideTank.serializeAttributes( + TARGETING::AttributeTank::ALLOC_TYPE_MALLOC, + MAILBOX_CHUNK_SIZE, l_attributes); + } + else + { + TARGETING::Target::theTargOverrideAttrTank(). + serializeAttributes( + TARGETING::AttributeTank::ALLOC_TYPE_MALLOC, + MAILBOX_CHUNK_SIZE, l_attributes); + } + + if (l_attributes.size()) + { + l_pErr = sendAttrsToFsp(MSG_SET_OVERRIDES, + static_cast<TARGETING::AttributeTank::TankLayer>(i), + l_attributes); + + if (l_pErr) + { + FAPI_ERR( + "sendAttrOverridesAndSyncsToFsp: Error sending overrides (%d)", + i); + errlCommit(l_pErr, HWPF_COMP_ID); + break; + } } } + } - if (l_pErr == NULL) + if (!l_pErr) + { + // Send Hostboot Attributes to Sync to the FSP + for (uint32_t i = TARGETING::AttributeTank::TANK_LAYER_FAPI; + i <= TARGETING::AttributeTank::TANK_LAYER_TARG; i++) { - // Send Hostboot Attributes to Sync to the FSP - std::vector<AttributeChunk> l_attributes; - - Singleton<fapi::SyncAttributeTank>::instance(). - getAllAttributes(AttributeTank::ALLOC_TYPE_MALLOC, - l_attributes); + std::vector<TARGETING::AttributeTank::AttributeSerializedChunk> + l_attributes; + + if (i == TARGETING::AttributeTank::TANK_LAYER_FAPI) + { + iv_syncTank.serializeAttributes( + TARGETING::AttributeTank::ALLOC_TYPE_MALLOC, + MAILBOX_CHUNK_SIZE, l_attributes); + } + else + { + TARGETING::Target::theTargSyncAttrTank(). + serializeAttributes( + TARGETING::AttributeTank::ALLOC_TYPE_MALLOC, + MAILBOX_CHUNK_SIZE, l_attributes); + } if (l_attributes.size()) { - l_pErr = sendAttrsToFsp(MSG_SET_SYNC_ATTS, l_attributes); + l_pErr = sendAttrsToFsp(MSG_SET_SYNC_ATTS, + static_cast<TARGETING::AttributeTank::TankLayer>(i), + l_attributes); if (l_pErr) { - FAPI_ERR("SendAttrOverridesToFsp: Error sending syncs to FSP"); + FAPI_ERR( + "sendAttrOverridesAndSyncsToFsp: Error sending syncs (%d)", + i); errlCommit(l_pErr, HWPF_COMP_ID); + break; } else { - // Clear Hostboot Attributes to Sync - Singleton<fapi::SyncAttributeTank>::instance(). - clearAllAttributes(); + // Clear Sync tank + if (i == TARGETING::AttributeTank::TANK_LAYER_FAPI) + { + iv_syncTank.clearAllAttributes(); + } + else + { + TARGETING::Target::theTargSyncAttrTank(). + clearAllAttributes(); + } } } } @@ -280,102 +406,177 @@ void sendAttrOverridesAndSyncsToFsp() } //****************************************************************************** -AttributeTank & theOverrideAttrTank() -{ - return Singleton<fapi::OverrideAttributeTank>::instance(); -} - -//****************************************************************************** -AttributeTank & theSyncAttrTank() +bool AttrOverrideSync::getAttrOverride(const fapi::AttributeId i_attrId, + const fapi::Target * const i_pTarget, + void * o_pVal) const { - return Singleton<fapi::SyncAttributeTank>::instance(); -} + // Very fast check to see if there are any overrides at all + if (!(iv_overrideTank.attributesExist())) + { + return false; + } -//****************************************************************************** -// This is used as a singleton and contains the lock used to serialize access -// to the OverrideAttributeTank -//****************************************************************************** -class OverrideAttributeTankLock -{ -public: - OverrideAttributeTankLock() + // Check to see if there are any overrides for this attr ID + if (!(iv_overrideTank.attributeExists(i_attrId))) { - mutex_init(&iv_mutex); + return false; } - ~OverrideAttributeTankLock() + // Do the work of figuring out the target's type/position and find out + // if there is an override for this target + uint32_t l_targetType = getTargetType(i_pTarget); + uint16_t l_pos = getTargetPos(i_pTarget); + uint8_t l_unitPos = getTargetUnitPos(i_pTarget); + + bool l_override = iv_overrideTank.getAttribute(i_attrId, l_targetType, + l_pos, l_unitPos, o_pVal); + + if (l_override) { - mutex_destroy(&iv_mutex); + FAPI_INF("getAttrOverride: Returning Override for 0x%08x", i_attrId); } - mutex_t iv_mutex; -}; + + return l_override; +} //****************************************************************************** -// This is used as a singleton and contains the lock used to serialize access -// to the SyncAttributeTank +bool AttrOverrideSync::getAttrOverrideFunc(const fapi::AttributeId i_attrId, + const fapi::Target * const i_pTarget, + void * o_pVal) +{ + return Singleton<AttrOverrideSync>::instance().getAttrOverride(i_attrId, + i_pTarget, o_pVal); +} + + //****************************************************************************** -class SyncAttributeTankLock +void AttrOverrideSync::setAttrActions(const fapi::AttributeId i_attrId, + const fapi::Target * const i_pTarget, + const uint32_t i_size, + const void * i_pVal) { -public: - SyncAttributeTankLock() + // Figure out if effort should be expended figuring out the target's type/ + // position in order to clear any non-const attribute overrides and/or to + // store the attribute for syncing to Cronus + + bool l_clearAnyNonConstOverride = false; + + // Very fast check to see if there are any overrides at all for this Attr ID + if (iv_overrideTank.attributesExist()) { - mutex_init(&iv_mutex); + // Fast check to see if there are any overrides for this attr ID + if (iv_overrideTank.attributeExists(i_attrId)) + { + l_clearAnyNonConstOverride = true; + } } - ~SyncAttributeTankLock() + bool l_syncAttribute = TARGETING::AttributeTank::syncEnabled(); + + if (l_clearAnyNonConstOverride || l_syncAttribute) { - mutex_destroy(&iv_mutex); - } - mutex_t iv_mutex; -}; + uint32_t l_targetType = getTargetType(i_pTarget); + uint16_t l_pos = getTargetPos(i_pTarget); + uint8_t l_unitPos = getTargetUnitPos(i_pTarget); -} // End attrOverrideSync namespace + if (l_clearAnyNonConstOverride) + { + // Clear any non const override for this attribute because the + // attribute is being written + iv_overrideTank.clearNonConstAttribute(i_attrId, l_targetType, + l_pos, l_unitPos); + } -//****************************************************************************** -// This is the Hostboot PLAT implementation of a FAPI function -//****************************************************************************** -void OverrideAttributeTank::platLock() const -{ - mutex_lock(&(Singleton<fapi::attrOverrideSync:: - OverrideAttributeTankLock>::instance().iv_mutex)); + if (l_syncAttribute) + { + // Write the attribute to the SyncAttributeTank to sync to Cronus + iv_syncTank.setAttribute(i_attrId, l_targetType, l_pos, l_unitPos, + 0, i_size, i_pVal); + } + } } //****************************************************************************** -// This is the Hostboot PLAT implementation of a FAPI function -//****************************************************************************** -void OverrideAttributeTank::platUnlock() const +void AttrOverrideSync::setAttrActionsFunc(const fapi::AttributeId i_attrId, + const fapi::Target * const i_pTarget, + const uint32_t i_size, + const void * i_pVal) { - mutex_unlock(&(Singleton<fapi::attrOverrideSync:: - OverrideAttributeTankLock>::instance().iv_mutex)); + Singleton<AttrOverrideSync>::instance().setAttrActions(i_attrId, i_pTarget, + i_size, i_pVal); } + //****************************************************************************** -// This is the Hostboot PLAT implementation of a FAPI function -//****************************************************************************** -void SyncAttributeTank::platLock() const +uint32_t AttrOverrideSync::getTargetType(const fapi::Target * const i_pTarget) { - mutex_lock(&(Singleton<fapi::attrOverrideSync:: - SyncAttributeTankLock>::instance().iv_mutex)); + uint32_t l_targetType = fapi::TARGET_TYPE_SYSTEM; + + if (i_pTarget != NULL) + { + l_targetType = i_pTarget->getType(); + } + + return l_targetType; } //****************************************************************************** -// This is the Hostboot PLAT implementation of a FAPI function -//****************************************************************************** -void SyncAttributeTank::platUnlock() const +uint16_t AttrOverrideSync::getTargetPos(const fapi::Target * const i_pTarget) { - mutex_unlock(&(Singleton<fapi::attrOverrideSync:: - SyncAttributeTankLock>::instance().iv_mutex)); + // Note that an error querying a parent chip is ignored and the function + // returns ATTR_POS_NA + uint16_t l_pos = TARGETING::AttributeTank::ATTR_POS_NA; + + if (i_pTarget != NULL) + { + // Get the Target pointer + TARGETING::Target * l_pTarget = + reinterpret_cast<TARGETING::Target*>(i_pTarget->get()); + + if (l_pTarget->getAttr<TARGETING::ATTR_CLASS>() == + TARGETING::CLASS_UNIT) + { + // Target is a chiplet. The position is the parent chip position + const TARGETING::Target * l_pChip = getParentChip(l_pTarget); + + if (l_pChip == NULL) + { + FAPI_ERR("getParentChip failed to return parent"); + } + else + { + l_pos = l_pChip->getAttr<TARGETING::ATTR_POSITION>(); + } + } + else + { + // Target is not a chiplet + l_pos = l_pTarget->getAttr<TARGETING::ATTR_POSITION>(); + } + } + + return l_pos; } //****************************************************************************** -// This is the Hostboot PLAT implementation of a FAPI function -//****************************************************************************** -bool SyncAttributeTank::platSyncEnabled() +uint8_t AttrOverrideSync::getTargetUnitPos(const fapi::Target * const i_pTarget) { - // TODO, RTC 42642. Check for CronusMode, probably using a FAPI Attribute - // but TBD. If CronusMode is not enabled then there should not be the - // performance hit of adding written attributes to the SyncAttributeTank - return false; + uint8_t l_unitPos = TARGETING::AttributeTank::ATTR_UNIT_POS_NA; + + if (i_pTarget != NULL) + { + // Get the Target pointer + TARGETING::Target * l_pTarget = + reinterpret_cast<TARGETING::Target*>(i_pTarget->get()); + + if (l_pTarget->getAttr<TARGETING::ATTR_CLASS>() == + TARGETING::CLASS_UNIT) + { + l_unitPos = l_pTarget->getAttr<TARGETING::ATTR_CHIP_UNIT>(); + } + } + + return l_unitPos; } } // End fapi namespace diff --git a/src/usr/hwpf/plat/fapiPlatTask.C b/src/usr/hwpf/plat/fapiPlatTask.C index 4232f7aae..a03cff99b 100644 --- a/src/usr/hwpf/plat/fapiPlatTask.C +++ b/src/usr/hwpf/plat/fapiPlatTask.C @@ -1,26 +1,25 @@ -/* IBM_PROLOG_BEGIN_TAG - * This is an automatically generated prolog. - * - * $Source: src/usr/hwpf/plat/fapiPlatTask.C $ - * - * IBM CONFIDENTIAL - * - * COPYRIGHT International Business Machines Corp. 2012 - * - * p1 - * - * Object Code Only (OCO) source materials - * Licensed Internal Code Source Materials - * IBM HostBoot Licensed Internal Code - * - * The source code for this program is not published or other- - * wise divested of its trade secrets, irrespective of what has - * been deposited with the U.S. Copyright Office. - * - * Origin: 30 - * - * IBM_PROLOG_END_TAG - */ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/usr/hwpf/plat/fapiPlatTask.C $ */ +/* */ +/* IBM CONFIDENTIAL */ +/* */ +/* COPYRIGHT International Business Machines Corp. 2012,2013 */ +/* */ +/* p1 */ +/* */ +/* Object Code Only (OCO) source materials */ +/* Licensed Internal Code Source Materials */ +/* IBM HostBoot Licensed Internal Code */ +/* */ +/* 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. */ +/* */ +/* Origin: 30 */ +/* */ +/* IBM_PROLOG_END_TAG */ /** * @file fapiPlatTask.C * @@ -31,7 +30,6 @@ // Includes //****************************************************************************** #include <initservice/taskargs.H> -#include <hwpf/fapi/fapiAttributeTank.H> #include <hwpf/plat/fapiPlatAttrOverrideSync.H> #include <hwpf/plat/fapiPlatTrace.H> @@ -42,7 +40,9 @@ namespace fapi // Global Variables //****************************************************************************** // Defined in fapiPlatAttrOverrideSync.C -extern Attribute g_attrOverride; +extern TARGETING::AttributeTank::AttributeHeader g_attrOverrideHeader; +extern uint8_t g_attrOverride[AttrOverrideSync::MAX_DIRECT_OVERRIDE_ATTR_SIZE_BYTES]; +extern uint8_t g_attrOverrideFapiTank; //****************************************************************************** // This function monitors for FSP mailbox messages @@ -50,15 +50,16 @@ extern Attribute g_attrOverride; void * platMonitorForFspMessages(void * i_pContext) { FAPI_IMP("Starting platMonitorForFspMessages"); - fapi::attrOverrideSync::monitorForFspMessages(); + fapi::theAttrOverrideSync().monitorForFspMessages(); return NULL; // Execution should never reach here } //****************************************************************************** // This function is run when the extended initservice loads the plat module // -// It writes the g_attrOverride global to ensure it is paged and pinned in -// memory. This variable is used by a debug tool to override HWPF Attributes +// It writes the global variables associated with direct attribute override to +// ensure they are paged and pinned in memory. These variables are used by a +// debug tool to override attributes // // It starts a task that monitors for FSP mailbox messages on the // HB_HWPF_ATTR_MSGQ message queue @@ -67,8 +68,10 @@ void platTaskEntry(errlHndl_t &io_errl) { FAPI_IMP("Starting platTaskEntry"); - // Write the g_attrOverride global - g_attrOverride.iv_val = 0; + // Write the global variables associated with direct attribute override + g_attrOverrideHeader.iv_attrId = 0; + g_attrOverride[0] = 0; + g_attrOverrideFapiTank = 0; // Start task that monitors for FSP mailbox messages task_create(fapi::platMonitorForFspMessages, NULL); diff --git a/src/usr/hwpf/test/fapiAttrTest.C b/src/usr/hwpf/test/fapiAttrTest.C new file mode 100644 index 000000000..1a97afaf3 --- /dev/null +++ b/src/usr/hwpf/test/fapiAttrTest.C @@ -0,0 +1,585 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/usr/hwpf/test/fapiAttrTest.C $ */ +/* */ +/* IBM CONFIDENTIAL */ +/* */ +/* COPYRIGHT International Business Machines Corp. 2013 */ +/* */ +/* p1 */ +/* */ +/* Object Code Only (OCO) source materials */ +/* Licensed Internal Code Source Materials */ +/* IBM HostBoot Licensed Internal Code */ +/* */ +/* 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. */ +/* */ +/* Origin: 30 */ +/* */ +/* IBM_PROLOG_END_TAG */ +/** + * @file fapiAttrTest.C + * + * @brief Implements FAPI Attribute unit test functions. + * + * This is provided by FAPI and can be pulled into any unit test framework. + * Each unit test returns 0 for success, else error value. + */ + +/* + * Change Log ****************************************************************** + * Flag Defect/Feature User Date Description + * ------ -------------- ---------- ----------- ---------------------------- + * mjjones 02/15/2013 Created. Ported from HWP. + */ + +#include <fapi.H> + +namespace fapi +{ + +//****************************************************************************** +// attrTest1. Test ATTR_SCRATCH_UINT8_1 +//****************************************************************************** +uint32_t attrTest1() +{ + uint32_t l_result = 0; + + do + { + fapi::ReturnCode l_rc; + + uint8_t l_uint8 = 0x87; + + // Test set + l_rc = FAPI_ATTR_SET(ATTR_SCRATCH_UINT8_1, NULL, l_uint8); + if (l_rc) + { + fapiLogError(l_rc); + FAPI_ERR("attrTest1: ATTR_SCRATCH_UINT8_1. Error from SET (1)"); + l_result = 1; + break; + } + + // Test get + l_uint8 = 8; + l_rc = FAPI_ATTR_GET(ATTR_SCRATCH_UINT8_1, NULL, l_uint8); + if (l_rc) + { + fapiLogError(l_rc); + FAPI_ERR("attrTest1: ATTR_SCRATCH_UINT8_1. Error from GET (2)"); + l_result = 2; + break; + } + + // Check value + if (l_uint8 != 0x87) + { + FAPI_ERR("attrTest1: ATTR_SCRATCH_UINT8_1. GET returned %d (3)", + l_uint8); + l_result = 3; + break; + } + + // Set to zero + l_uint8 = 0; + l_rc = FAPI_ATTR_SET(ATTR_SCRATCH_UINT8_1, NULL, l_uint8); + if (l_rc) + { + fapiLogError(l_rc); + FAPI_ERR("attrTest1: ATTR_SCRATCH_UINT8_1. Error from SET (4)"); + l_result = 4; + break; + } + + } while (0); + + if (!l_result) + { + FAPI_INF("attrTest1: unit test success"); + } + return l_result; +} + +//****************************************************************************** +// attrTest2. Test ATTR_SCRATCH_UINT32_1 +//****************************************************************************** +uint32_t attrTest2() +{ + uint32_t l_result = 0; + + do + { + fapi::ReturnCode l_rc; + + uint32_t l_uint32 = 0x80000001; + + // Test set + l_rc = FAPI_ATTR_SET(ATTR_SCRATCH_UINT32_1, NULL, l_uint32); + if (l_rc) + { + fapiLogError(l_rc); + FAPI_ERR("attrTest2: ATTR_SCRATCH_UINT32_1. Error from SET (1)"); + l_result = 1; + break; + } + + // Test get + l_uint32 = 8; + l_rc = FAPI_ATTR_GET(ATTR_SCRATCH_UINT32_1, NULL, l_uint32); + if (l_rc) + { + fapiLogError(l_rc); + FAPI_ERR("attrTest2: ATTR_SCRATCH_UINT32_1. Error from GET (2)"); + l_result = 2; + break; + } + + // Check value + if (l_uint32 != 0x80000001) + { + FAPI_ERR("attrTest2: ATTR_SCRATCH_UINT32_1. GET returned %d (3)", + l_uint32); + l_result = 3; + break; + } + + // Set to zero + l_uint32 = 0; + l_rc = FAPI_ATTR_SET(ATTR_SCRATCH_UINT32_1, NULL, l_uint32); + if (l_rc) + { + fapiLogError(l_rc); + FAPI_ERR("attrTest2: ATTR_SCRATCH_UINT32_1. Error from SET (4)"); + l_result = 4; + break; + } + + } while (0); + + if (!l_result) + { + FAPI_INF("attrTest2: unit test success"); + } + return l_result; +} + +//****************************************************************************** +// attrTest3. Test ATTR_SCRATCH_UINT64_1 +//****************************************************************************** +uint32_t attrTest3() +{ + uint32_t l_result = 0; + + do + { + fapi::ReturnCode l_rc; + + uint64_t l_uint64 = 3; + + // Test set + l_rc = FAPI_ATTR_SET(ATTR_SCRATCH_UINT64_1, NULL, l_uint64); + if (l_rc) + { + fapiLogError(l_rc); + FAPI_ERR("attrTest3: ATTR_SCRATCH_UINT64_1. Error from SET (1)"); + l_result = 1; + break; + } + + // Test get + l_uint64 = 8; + l_rc = FAPI_ATTR_GET(ATTR_SCRATCH_UINT64_1, NULL, l_uint64); + if (l_rc) + { + fapiLogError(l_rc); + FAPI_ERR("attrTest3: ATTR_SCRATCH_UINT64_1. Error from GET (2)"); + l_result = 2; + break; + } + + // Check value + if (l_uint64 != 3) + { + FAPI_ERR("attrTest3: ATTR_SCRATCH_UINT64_1. GET returned %d (3)", + static_cast<uint32_t>(l_uint64)); + l_result = 3; + break; + } + + // Set to zero + l_uint64 = 0; + l_rc = FAPI_ATTR_SET(ATTR_SCRATCH_UINT64_1, NULL, l_uint64); + if (l_rc) + { + fapiLogError(l_rc); + FAPI_ERR("attrTest3: ATTR_SCRATCH_UINT64_1. Error from SET (4)"); + l_result = 4; + break; + } + + } while (0); + + if (!l_result) + { + FAPI_INF("attrTest3: unit test success"); + } + return l_result; +} + +//****************************************************************************** +// attrTest4. Test ATTR_SCRATCH_UINT8_ARRAY_1 +//****************************************************************************** +uint32_t attrTest4() +{ + uint32_t l_result = 0; + + do + { + fapi::ReturnCode l_rc; + + uint8_t l_uint8array1[32]; + + // Test set + for (uint32_t i = 0; i < 32; i++) + { + l_uint8array1[i] = i + 1; + } + + l_rc = FAPI_ATTR_SET(ATTR_SCRATCH_UINT8_ARRAY_1, NULL, l_uint8array1); + if (l_rc) + { + fapiLogError(l_rc); + FAPI_ERR("attrTest4: ATTR_SCRATCH_UINT8_ARRAY_1. Error from SET (1)"); + l_result = 1; + break; + } + + // Test get + for (uint32_t i = 0; i < 32; i++) + { + l_uint8array1[i] = 0; + } + + l_rc = FAPI_ATTR_GET(ATTR_SCRATCH_UINT8_ARRAY_1, NULL, l_uint8array1); + if (l_rc) + { + fapiLogError(l_rc); + FAPI_ERR("attrTest4: ATTR_SCRATCH_UINT8_ARRAY_1. Error from GET (2)"); + l_result = 2; + break; + } + + // Check value + for (uint32_t i = 0; i < 32; i++) + { + if (l_uint8array1[i] != (i + 1)) + { + FAPI_ERR("attrTest4: ATTR_SCRATCH_UINT8_ARRAY_1. GET [%d] returned %d (3)", + i, l_uint8array1[i]); + l_result = 3; + break; + } + } + + if (l_result) + { + break; + } + + // Set to zero + for (uint32_t i = 0; i < 32; i++) + { + l_uint8array1[i] = 0; + } + + l_rc = FAPI_ATTR_SET(ATTR_SCRATCH_UINT8_ARRAY_1, NULL, l_uint8array1); + if (l_rc) + { + fapiLogError(l_rc); + FAPI_ERR("attrTest4: ATTR_SCRATCH_UINT8_ARRAY_1. Error from SET (4)"); + l_result = 4; + break; + } + + } while (0); + + if (!l_result) + { + FAPI_INF("attrTest4: unit test success"); + } + return l_result; +} + +//****************************************************************************** +// attrTest5. Test ATTR_SCRATCH_UINT32_ARRAY_2 +//****************************************************************************** +uint32_t attrTest5() +{ + uint32_t l_result = 0; + + do + { + fapi::ReturnCode l_rc; + + uint32_t l_uint32 = 1; + uint32_t l_uint32array2[2][3]; + + // Test set + l_uint32 = 1; + for (uint32_t i = 0; i < 2; i++) + { + for (uint32_t j = 0; j < 3; j++) + { + l_uint32array2[i][j] = l_uint32++; + } + } + + l_rc = FAPI_ATTR_SET(ATTR_SCRATCH_UINT32_ARRAY_2, NULL, l_uint32array2); + if (l_rc) + { + fapiLogError(l_rc); + FAPI_ERR("attrTest5: ATTR_SCRATCH_UINT32_ARRAY_2. Error from SET (1)"); + l_result = 1; + break; + } + + // Test get + for (uint32_t i = 0; i < 2; i++) + { + for (uint32_t j = 0; j < 3; j++) + { + l_uint32array2[i][j] = 0; + } + } + + l_rc = FAPI_ATTR_GET(ATTR_SCRATCH_UINT32_ARRAY_2, NULL, l_uint32array2); + if (l_rc) + { + fapiLogError(l_rc); + FAPI_ERR("attrTest5: ATTR_SCRATCH_UINT32_ARRAY_2. Error from GET (2)"); + l_result = 2; + break; + } + + // Check value + l_uint32 = 1; + for (uint32_t i = 0; i < 2; i++) + { + for (uint32_t j = 0; j < 3; j++) + { + if (l_uint32array2[i][j] != l_uint32++) + { + FAPI_ERR("attrTest5: ATTR_SCRATCH_UINT32_ARRAY_2. GET [%d:%d] returned %d (3)", + i, j, l_uint32array2[i][j]); + l_result = 3; + break; + } + } + if (l_result) + { + break; + } + } + + if (l_result) + { + break; + } + + // Set to zero + for (uint32_t i = 0; i < 2; i++) + { + for (uint32_t j = 0; j < 3; j++) + { + l_uint32array2[i][j]= 0; + } + } + + l_rc = FAPI_ATTR_SET(ATTR_SCRATCH_UINT32_ARRAY_2, NULL, l_uint32array2); + if (l_rc) + { + fapiLogError(l_rc); + FAPI_ERR("attrTest5: ATTR_SCRATCH_UINT32_ARRAY_2. Error from SET (4)"); + l_result = 4; + break; + } + + } while (0); + + if (!l_result) + { + FAPI_INF("attrTest5: unit test success"); + } + return l_result; +} + +//****************************************************************************** +// attrTest6. Test ATTR_SCRATCH_UINT64_ARRAY_2 +//****************************************************************************** +uint32_t attrTest6() +{ + uint32_t l_result = 0; + + do + { + fapi::ReturnCode l_rc; + + uint64_t l_uint64 = 1; + uint64_t l_uint64array2[2][2]; + + // Test set + l_uint64 = 1; + for (uint32_t i = 0; i < 2; i++) + { + for (uint32_t j = 0; j < 2; j++) + { + l_uint64array2[i][j] = l_uint64++; + } + } + + l_rc = FAPI_ATTR_SET(ATTR_SCRATCH_UINT64_ARRAY_2, NULL, l_uint64array2); + if (l_rc) + { + fapiLogError(l_rc); + FAPI_ERR("attrTest6: ATTR_SCRATCH_UINT64_ARRAY_2. Error from SET (1)"); + l_result = 1; + break; + } + + // Test get + for (uint32_t i = 0; i < 2; i++) + { + for (uint32_t j = 0; j < 2; j++) + { + l_uint64array2[i][j] = 0; + } + } + + l_rc = FAPI_ATTR_GET(ATTR_SCRATCH_UINT64_ARRAY_2, NULL, l_uint64array2); + if (l_rc) + { + fapiLogError(l_rc); + FAPI_ERR("attrTest6: ATTR_SCRATCH_UINT64_ARRAY_2. Error from GET (2)"); + l_result = 2; + break; + } + + // Check value + l_uint64 = 1; + for (uint32_t i = 0; i < 2; i++) + { + for (uint32_t j = 0; j < 2; j++) + { + if (l_uint64array2[i][j] != l_uint64++) + { + FAPI_ERR("attrTest6: ATTR_SCRATCH_UINT64_ARRAY_2. GET [%d:%d] returned %d (3)", + i, j, static_cast<uint32_t>(l_uint64array2[i][j])); + l_result = 3; + break; + } + } + if (l_result) + { + break; + } + } + + if (l_result) + { + break; + } + + // Set to zero + for (uint32_t i = 0; i < 2; i++) + { + for (uint32_t j = 0; j < 2; j++) + { + l_uint64array2[i][j]= 0; + } + } + + l_rc = FAPI_ATTR_SET(ATTR_SCRATCH_UINT64_ARRAY_2, NULL, l_uint64array2); + if (l_rc) + { + fapiLogError(l_rc); + FAPI_ERR("attrTest6: ATTR_SCRATCH_UINT64_ARRAY_2. Error from SET (4)"); + l_result = 4; + break; + } + } while (0); + + if (!l_result) + { + FAPI_INF("attrTest6: unit test success"); + } + return l_result; +} + +//****************************************************************************** +// attrTest7. Test setting and getting an enum value from a scratch attribute +//****************************************************************************** +uint32_t attrTest7() +{ + uint32_t l_result = 0; + + do + { + fapi::ReturnCode l_rc; + + uint64_t l_uint64 = fapi::ENUM_ATTR_SCRATCH_UINT64_2_VAL_C; + + // Test set + l_rc = FAPI_ATTR_SET(ATTR_SCRATCH_UINT64_2, NULL, l_uint64); + if (l_rc) + { + fapiLogError(l_rc); + FAPI_ERR("attrTest7: ATTR_SCRATCH_UINT64_2. Error from SET (enum) (1)"); + l_result = 1; + break; + } + + // Test get + l_uint64 = 0; + l_rc = FAPI_ATTR_GET(ATTR_SCRATCH_UINT64_2, NULL, l_uint64); + if (l_rc) + { + fapiLogError(l_rc); + FAPI_ERR("attrTest7: ATTR_SCRATCH_UINT64_2. Error from GET (enum) (2)"); + l_result = 2; + break; + } + + // Check value + if (l_uint64 != fapi::ENUM_ATTR_SCRATCH_UINT64_2_VAL_C) + { + FAPI_ERR("attrTest7: ATTR_SCRATCH_UINT64_2. GET returned %d (enum) (3)", + static_cast<uint32_t>(l_uint64)); + l_result = 3; + break; + } + + // Set to zero + l_uint64 = 0; + l_rc = FAPI_ATTR_SET(ATTR_SCRATCH_UINT64_2, NULL, l_uint64); + if (l_rc) + { + fapiLogError(l_rc); + FAPI_ERR("attrTest7: ATTR_SCRATCH_UINT64_2. Error from SET (enum2) (4)"); + l_result = 4; + break; + } + + } while (0); + + if (!l_result) + { + FAPI_INF("attrTest7: unit test success"); + } + return l_result; +} + +} diff --git a/src/usr/hwpf/test/fapiattrtest.H b/src/usr/hwpf/test/fapiattrtest.H new file mode 100644 index 000000000..4610acb50 --- /dev/null +++ b/src/usr/hwpf/test/fapiattrtest.H @@ -0,0 +1,98 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/usr/hwpf/test/fapiattrtest.H $ */ +/* */ +/* IBM CONFIDENTIAL */ +/* */ +/* COPYRIGHT International Business Machines Corp. 2013 */ +/* */ +/* p1 */ +/* */ +/* Object Code Only (OCO) source materials */ +/* Licensed Internal Code Source Materials */ +/* IBM HostBoot Licensed Internal Code */ +/* */ +/* 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. */ +/* */ +/* Origin: 30 */ +/* */ +/* IBM_PROLOG_END_TAG */ +#ifndef FAPIATTRTEST_H +#define FAPIATTRTEST_H + +/** + * @file fapiattrtanktest.H + * + * @brief Test case for FAPI AttributeTank +*/ + +#include <cxxtest/TestSuite.H> +#include "fapiAttrTest.C" + +using namespace fapi; + +class FapiAttrTest: public CxxTest::TestSuite +{ +public: + + void test1(void) + { + if (attrTest1() != 0) + { + TS_FAIL("attrTest1. Fail"); + } + } + + void test2(void) + { + if (attrTest2() != 0) + { + TS_FAIL("attrTest2. Fail"); + } + } + + void test3(void) + { + if (attrTest3() != 0) + { + TS_FAIL("attrTest3. Fail"); + } + } + + void test4(void) + { + if (attrTest4() != 0) + { + TS_FAIL("attrTest4. Fail"); + } + } + + void test5(void) + { + if (attrTest5() != 0) + { + TS_FAIL("attrTest5. Fail"); + } + } + + void test6(void) + { + if (attrTest6() != 0) + { + TS_FAIL("attrTest6. Fail"); + } + } + + void test7(void) + { + if (attrTest7() != 0) + { + TS_FAIL("attrTest7. Fail"); + } + } +}; + +#endif diff --git a/src/usr/hwpf/test/hwpftest.H b/src/usr/hwpf/test/hwpftest.H index ebf401df9..f2e9604b5 100644 --- a/src/usr/hwpf/test/hwpftest.H +++ b/src/usr/hwpf/test/hwpftest.H @@ -251,69 +251,6 @@ public: } /** - * @brief Test HWPF Attributes: call a test procedure that exercises - * FAPI attributes - */ - void testHwpf4() - { - errlHndl_t l_err = NULL; - - // Get the first MBA chiplet - fapi::Target l_mbaChiplet; - { - TARGETING::PredicateCTM l_pred(TARGETING::CLASS_UNIT, TARGETING::TYPE_MBA); - TARGETING::TargetRangeFilter l_filter(TARGETING::targetService().begin(), - TARGETING::targetService().end(), - &l_pred); - if (l_filter) - { - l_mbaChiplet.setType(fapi::TARGET_TYPE_MBA_CHIPLET); - l_mbaChiplet.set(*l_filter); - } - else - { - FAPI_ERR("testHwpf4: No MBAs found"); - TS_FAIL("testHwpf4: No MBAs found"); - return; - } - } - - // Get the first proc chip - fapi::Target l_procChip; - { - TARGETING::PredicateCTM l_pred(TARGETING::CLASS_CHIP, TARGETING::TYPE_PROC); - TARGETING::TargetRangeFilter l_filter(TARGETING::targetService().begin(), - TARGETING::targetService().end(), - &l_pred); - if (l_filter) - { - l_procChip.setType(fapi::TARGET_TYPE_PROC_CHIP); - l_procChip.set(*l_filter); - } - else - { - FAPI_ERR("testHwpf4: No proc chips found"); - TS_FAIL("testHwpf4: No proc chips found"); - return; - } - } - - FAPI_INVOKE_HWP(l_err, hwpTestAttributes, l_mbaChiplet, l_procChip); - - if (l_err) - { - TS_FAIL("testHwpf4: Unit Test failed. " - "hwpTestAttributes failed. Error logged"); - errlCommit(l_err,HWPF_COMP_ID); - } - else - { - TS_TRACE("testHwpf4: Unit Test passed. " - "hwpTestAttributes passed. Error logged"); - } - } - - /** * @brief Test HWPF InitFile: call the procedure that exercises a * sample initfile */ diff --git a/src/usr/initservice/istepdispatcher/istepdispatcher.C b/src/usr/initservice/istepdispatcher/istepdispatcher.C index 6f5eeb551..409c070d9 100644 --- a/src/usr/initservice/istepdispatcher/istepdispatcher.C +++ b/src/usr/initservice/istepdispatcher/istepdispatcher.C @@ -814,7 +814,7 @@ void IStepDispatcher::handleMoreWorkNeededMsg ( bool i_first ) // Send the potentially modified set of HWPF Attribute overrides and any // HWPF Attributes to sync to the FSP - fapi::attrOverrideSync::sendAttrOverridesAndSyncsToFsp(); + fapi::theAttrOverrideSync().sendAttrOverridesAndSyncsToFsp(); msg_respond( iv_msgQ, iv_Msg ); diff --git a/src/usr/targeting/common/attributeTank.C b/src/usr/targeting/common/attributeTank.C new file mode 100644 index 000000000..739f9c97a --- /dev/null +++ b/src/usr/targeting/common/attributeTank.C @@ -0,0 +1,405 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/usr/targeting/common/attributeTank.C $ */ +/* */ +/* IBM CONFIDENTIAL */ +/* */ +/* COPYRIGHT International Business Machines Corp. 2013 */ +/* */ +/* p1 */ +/* */ +/* Object Code Only (OCO) source materials */ +/* Licensed Internal Code Source Materials */ +/* IBM HostBoot Licensed Internal Code */ +/* */ +/* 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. */ +/* */ +/* Origin: 30 */ +/* */ +/* IBM_PROLOG_END_TAG */ +/** + * @file attributeTank.C + * + * @brief Implements the AttributeTank and associated classes. + */ + +/* + * Change Log ****************************************************************** + * Flag Defect/Feature User Date Description + * ------ -------------- ---------- ----------- ---------------------------- + * mjjones 06/07/2012 Created + * mjjones 02/13/2013 Moved to Targeting and major + * design changes + */ +#include <stdlib.h> +#include <string.h> +#include <targeting/common/attributeTank.H> +#include <targeting/common/trace.H> + +namespace TARGETING +{ + +//****************************************************************************** +AttributeTank::AttributeHeader::AttributeHeader() : + iv_attrId(0), iv_targetType(0), iv_pos(0), iv_unitPos(0), iv_flags(0), + iv_valSize(0) +{ + +} + +//****************************************************************************** +AttributeTank::AttributeSerializedChunk::AttributeSerializedChunk() : + iv_size(0), iv_pAttributes(NULL) +{ + +} + +//****************************************************************************** +AttributeTank::AttributeTank() : + iv_attributesExist(false) +{ + TARG_MUTEX_INIT(iv_mutex); +} + +//****************************************************************************** +AttributeTank::~AttributeTank() +{ + for (AttributesItr_t l_itr = iv_attributes.begin(); + l_itr != iv_attributes.end(); ++l_itr) + { + delete (*l_itr); + (*l_itr) = NULL; + } + + TARG_MUTEX_DESTROY(iv_mutex); +} + +//****************************************************************************** +bool AttributeTank::syncEnabled() +{ + // TODO, RTC 42642. Check for CronusMode, probably using an attribute + // but TBD. If CronusMode is not enabled then there should not be the + // performance hit of adding written attributes to a SyncAttributeTank + return false; +} + +//****************************************************************************** +void AttributeTank::clearAllAttributes() +{ + TARG_MUTEX_LOCK(iv_mutex); + + for (AttributesItr_t l_itr = iv_attributes.begin(); + l_itr != iv_attributes.end(); ++l_itr) + { + delete (*l_itr); + (*l_itr) = NULL; + } + + iv_attributesExist = false; + iv_attributes.clear(); + + TARG_MUTEX_UNLOCK(iv_mutex); +} + +//****************************************************************************** +void AttributeTank::clearNonConstAttribute(const uint32_t i_attrId, + const uint32_t i_targetType, + const uint16_t i_pos, + const uint8_t i_unitPos) +{ + TARG_MUTEX_LOCK(iv_mutex); + + for (AttributesItr_t l_itr = iv_attributes.begin(); + l_itr != iv_attributes.end(); ++l_itr) + { + if ( ((*l_itr)->iv_hdr.iv_attrId == i_attrId) && + ((*l_itr)->iv_hdr.iv_targetType == i_targetType) && + ((*l_itr)->iv_hdr.iv_pos == i_pos) && + ((*l_itr)->iv_hdr.iv_unitPos == i_unitPos) ) + { + if (!((*l_itr)->iv_hdr.iv_flags & ATTR_FLAG_CONST)) + { + delete (*l_itr); + (*l_itr) = NULL; + iv_attributes.erase(l_itr); + + if (iv_attributes.empty()) + { + iv_attributesExist = false; + } + } + + break; + } + } + + TARG_MUTEX_UNLOCK(iv_mutex); +} + +//****************************************************************************** +void AttributeTank::setAttribute(const uint32_t i_attrId, + const uint32_t i_targetType, + const uint16_t i_pos, + const uint8_t i_unitPos, + const uint8_t i_flags, + const uint32_t i_valSize, + const void * i_pVal) +{ + TARG_MUTEX_LOCK(iv_mutex); + + // Search for an existing matching attribute + bool l_found = false; + + for (AttributesItr_t l_itr = iv_attributes.begin(); + l_itr != iv_attributes.end(); ++l_itr) + { + if ( ((*l_itr)->iv_hdr.iv_attrId == i_attrId) && + ((*l_itr)->iv_hdr.iv_targetType == i_targetType) && + ((*l_itr)->iv_hdr.iv_pos == i_pos) && + ((*l_itr)->iv_hdr.iv_unitPos == i_unitPos) && + ((*l_itr)->iv_hdr.iv_valSize == i_valSize) ) + { + // Found existing attribute, update it unless the existing attribute + // is const and the new attribute is non-const + if (!( ((*l_itr)->iv_hdr.iv_flags & ATTR_FLAG_CONST) && + (!(i_flags & ATTR_FLAG_CONST)) ) ) + { + (*l_itr)->iv_hdr.iv_flags = i_flags; + memcpy((*l_itr)->iv_pVal, i_pVal, i_valSize); + } + l_found = true; + break; + } + } + + if (!l_found) + { + // Add a new attribute to the tank + Attribute * l_pAttr = new Attribute(); + + l_pAttr->iv_hdr.iv_attrId = i_attrId; + l_pAttr->iv_hdr.iv_targetType = i_targetType; + l_pAttr->iv_hdr.iv_pos = i_pos; + l_pAttr->iv_hdr.iv_unitPos = i_unitPos; + l_pAttr->iv_hdr.iv_flags = i_flags; + l_pAttr->iv_hdr.iv_valSize = i_valSize; + l_pAttr->iv_pVal = new uint8_t[i_valSize]; + memcpy(l_pAttr->iv_pVal, i_pVal, i_valSize); + + iv_attributesExist = true; + iv_attributes.push_back(l_pAttr); + } + + TARG_MUTEX_UNLOCK(iv_mutex); +} + +//****************************************************************************** +bool AttributeTank::getAttribute(const uint32_t i_attrId, + const uint32_t i_targetType, + const uint16_t i_pos, + const uint8_t i_unitPos, + void * o_pVal) const +{ + TARG_MUTEX_LOCK(iv_mutex); + + bool l_found = false; + + for (AttributesCItr_t l_itr = iv_attributes.begin(); l_itr + != iv_attributes.end(); ++l_itr) + { + // Allow match if attribute applies to all positions + if ( ((*l_itr)->iv_hdr.iv_attrId == i_attrId) && + ((*l_itr)->iv_hdr.iv_targetType == i_targetType) && + (((*l_itr)->iv_hdr.iv_pos == ATTR_POS_NA) || + ((*l_itr)->iv_hdr.iv_pos == i_pos)) && + (((*l_itr)->iv_hdr.iv_unitPos == ATTR_UNIT_POS_NA) || + ((*l_itr)->iv_hdr.iv_unitPos == i_unitPos)) ) + { + l_found = true; + memcpy(o_pVal, (*l_itr)->iv_pVal, (*l_itr)->iv_hdr.iv_valSize); + break; + } + } + + TARG_MUTEX_UNLOCK(iv_mutex); + return l_found; +} + +//****************************************************************************** +void AttributeTank::serializeAttributes( + const AllocType i_allocType, + const uint32_t i_chunkSize, + std::vector<AttributeSerializedChunk> & o_attributes) const +{ + TARG_MUTEX_LOCK(iv_mutex); + + // Temporary buffer of the requested chunk size for storing attributes + uint8_t * l_pBuffer = new uint8_t[i_chunkSize]; + uint32_t l_index = 0; + + AttributesCItr_t l_itr = iv_attributes.begin(); + + while (l_itr != iv_attributes.end()) + { + // Fill up the buffer with as many attributes as possible + while (l_itr != iv_attributes.end()) + { + if ((l_index + sizeof(AttributeHeader) + + (*l_itr)->iv_hdr.iv_valSize) > i_chunkSize) + { + // Attribute will not fit into the buffer + if (l_index == 0) + { + // Attribute will not fit in an empty buffer of the + // requested chunk size, this should not happen, if it does, + // just move to the next attribute + TRACFCOMP(g_trac_targeting, + "serializeAttributes: Error, attr too big to serialize (0x%x)", + (*l_itr)->iv_hdr.iv_valSize); + l_itr++; + } + else + { + // Attribute will not fit in a partially filled buffer, the + // buffer is ready to send to the user + break; + } + } + else + { + // Copy the attribute header to the buffer + AttributeHeader * l_pHeader = + reinterpret_cast<AttributeHeader *>(l_pBuffer + l_index); + *l_pHeader = (*l_itr)->iv_hdr; + l_index += sizeof(AttributeHeader); + + // Copy the attribute value to the buffer + memcpy((l_pBuffer + l_index), (*l_itr)->iv_pVal, + (*l_itr)->iv_hdr.iv_valSize); + l_index += (*l_itr)->iv_hdr.iv_valSize; + + l_itr++; + } + } + + if (l_index) + { + // Create a chunk and add it to the caller's vector + AttributeSerializedChunk l_chunk; + + if (i_allocType == ALLOC_TYPE_MALLOC) + { + l_chunk.iv_pAttributes = + static_cast<uint8_t *>(malloc(l_index)); + } + else + { + l_chunk.iv_pAttributes = new uint8_t[l_index]; + } + + memcpy(l_chunk.iv_pAttributes, l_pBuffer, l_index); + l_chunk.iv_size = l_index; + o_attributes.push_back(l_chunk); + + // Reuse the buffer for the next attribute + l_index = 0; + } + } + + delete [] l_pBuffer; + + TARG_MUTEX_UNLOCK(iv_mutex); +} + +//****************************************************************************** +bool AttributeTank::attributeExists(const uint32_t i_attrId) const +{ + // Note. The use-case is for the caller to call attributesExist() before + // calling this function, i.e. the caller has already verified that + // attributes exist in the tank. No need for this function to call + // attributesExist() again. + TARG_MUTEX_LOCK(iv_mutex); + + bool l_found = false; + + for (AttributesCItr_t l_itr = iv_attributes.begin(); l_itr + != iv_attributes.end(); ++l_itr) + { + if ((*l_itr)->iv_hdr.iv_attrId == i_attrId) + { + l_found = true; + break; + } + } + + TARG_MUTEX_UNLOCK(iv_mutex); + return l_found; +} + +//****************************************************************************** +void AttributeTank::deserializeAttributes( + const AttributeSerializedChunk & i_attributes) +{ + TARG_MUTEX_LOCK(iv_mutex); + + uint32_t l_index = 0; + + while (l_index < i_attributes.iv_size) + { + AttributeHeader * l_pAttrHdr = + reinterpret_cast<AttributeHeader *> + (i_attributes.iv_pAttributes + l_index); + + if (sizeof(AttributeHeader) > (i_attributes.iv_size - l_index)) + { + // Remaining chunk smaller than attribute header, quit + TRACFCOMP(g_trac_targeting, + "deserializeAttributes: Error, header too big for chunk (0x%x)", + (i_attributes.iv_size - l_index)); + break; + } + + l_index += sizeof(AttributeHeader); + + if (l_pAttrHdr->iv_valSize > (i_attributes.iv_size - l_index)) + { + // Remaining chunk smaller than attribute value, quit + TRACFCOMP(g_trac_targeting, + "deserializeAttributes: Error, attr too big for chunk (0x%x:0x%x)", + l_pAttrHdr->iv_valSize, (i_attributes.iv_size - l_index)); + break; + } + + // Create a new Attribute and add it to the tank + Attribute * l_pAttr = new Attribute(); + l_pAttr->iv_hdr = *l_pAttrHdr; + l_pAttr->iv_pVal = new uint8_t[l_pAttrHdr->iv_valSize]; + memcpy(l_pAttr->iv_pVal, (i_attributes.iv_pAttributes + l_index), + l_pAttrHdr->iv_valSize); + + l_index += l_pAttrHdr->iv_valSize; + iv_attributesExist = true; + iv_attributes.push_back(l_pAttr); + } + + TARG_MUTEX_UNLOCK(iv_mutex); +} + +//****************************************************************************** +AttributeTank::Attribute::Attribute() : + iv_pVal(NULL) +{ + +} + +//****************************************************************************** +AttributeTank::Attribute::~Attribute() +{ + delete[] iv_pVal; + iv_pVal = NULL; +} + +} diff --git a/src/usr/targeting/common/common.mk b/src/usr/targeting/common/common.mk index 9608bd86e..78cded51f 100644 --- a/src/usr/targeting/common/common.mk +++ b/src/usr/targeting/common/common.mk @@ -1,25 +1,25 @@ -# IBM_PROLOG_BEGIN_TAG -# This is an automatically generated prolog. -# -# $Source: src/usr/targeting/common/common.mk $ -# -# IBM CONFIDENTIAL -# -# COPYRIGHT International Business Machines Corp. 2011,2012 -# -# p1 -# -# Object Code Only (OCO) source materials -# Licensed Internal Code Source Materials -# IBM HostBoot Licensed Internal Code -# -# 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. -# -# Origin: 30 -# -# IBM_PROLOG_END_TAG +# IBM_PROLOG_BEGIN_TAG +# This is an automatically generated prolog. +# +# $Source: src/usr/targeting/common/common.mk $ +# +# IBM CONFIDENTIAL +# +# COPYRIGHT International Business Machines Corp. 2011,2013 +# +# p1 +# +# Object Code Only (OCO) source materials +# Licensed Internal Code Source Materials +# IBM HostBoot Licensed Internal Code +# +# 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. +# +# Origin: 30 +# +# IBM_PROLOG_END_TAG ################################################################################ # # @file targeting/common/common.mk @@ -48,7 +48,7 @@ TARGET_OBJS = \ entitypath.o OTHER_OBJS = \ - util.o utilFilter.o + util.o utilFilter.o attributeTank.o # Common COMMON_TARGETING_OBJS = \ diff --git a/src/usr/targeting/common/target.C b/src/usr/targeting/common/target.C index b91cc98fe..6f695cad7 100644 --- a/src/usr/targeting/common/target.C +++ b/src/usr/targeting/common/target.C @@ -42,6 +42,7 @@ #include <targeting/common/util.H> #include <targeting/common/trace.H> #include <targeting/common/predicates/predicateattrval.H> +#include <targeting/common/utilFilter.H> namespace TARGETING { @@ -71,13 +72,52 @@ bool Target::_tryGetAttr( { #define TARG_FN "_tryGetAttr()" - void* l_pAttrData = NULL; - (void) _getAttrPtr(i_attr, l_pAttrData); - if (l_pAttrData) + bool l_found = false; + + // Very fast check if there are any overrides at all + if (unlikely(cv_overrideTank.attributesExist())) { - memcpy(io_pAttrData, l_pAttrData, i_size); + // Check if there are any overrides for this attr ID + if (cv_overrideTank.attributeExists(i_attr)) + { + // The following attributes can be used to determine the position + // of a target (for a unit, the position is the parent's position) + // Do not check for overrides for these because an infinite loop + // will result from recursively checking for overrides + if ((i_attr != ATTR_PHYS_PATH) && + (i_attr != ATTR_AFFINITY_PATH) && + (i_attr != ATTR_POWER_PATH)) + { + // Find if there is an attribute override + uint32_t l_type = getAttrTankTargetType(); + uint16_t l_pos = getAttrTankTargetPos(); + uint8_t l_unitPos = getAttrTankTargetUnitPos(); + + l_found = cv_overrideTank.getAttribute(i_attr, l_type, + l_pos, l_unitPos, io_pAttrData); + + if (l_found) + { + TRACFCOMP(g_trac_targeting, "Returning Override for 0x%08x", + i_attr); + } + } + } } - return (l_pAttrData != NULL); + + if (!l_found) + { + // No attribute override, get the real attribute + void* l_pAttrData = NULL; + (void) _getAttrPtr(i_attr, l_pAttrData); + if (l_pAttrData) + { + memcpy(io_pAttrData, l_pAttrData, i_size); + l_found = true; + } + } + + return l_found; #undef TARG_FN } @@ -93,6 +133,47 @@ bool Target::_trySetAttr( { #define TARG_FN "_trySetAttr()" + // Figure out if effort should be expended figuring out the target's type/ + // position in order to clear any non-const attribute overrides and/or to + // store the attribute for syncing to Cronus + + bool l_clearAnyNonConstOverride = false; + + // Very fast check if there are any overrides at all for this Attr ID + if (unlikely(cv_overrideTank.attributesExist())) + { + // Check if there are any overrides for this attr ID + if (cv_overrideTank.attributeExists(i_attr)) + { + l_clearAnyNonConstOverride = true; + } + } + + bool l_syncAttribute = AttributeTank::syncEnabled(); + + if (unlikely(l_clearAnyNonConstOverride || l_syncAttribute)) + { + uint32_t l_type = getAttrTankTargetType(); + uint16_t l_pos = getAttrTankTargetPos(); + uint8_t l_unitPos = getAttrTankTargetUnitPos(); + + if (l_clearAnyNonConstOverride) + { + // Clear any non const override for this attribute because the + // attribute is being written + cv_overrideTank.clearNonConstAttribute(i_attr, l_type, l_pos, + l_unitPos); + } + + if (l_syncAttribute) + { + // Write the attribute to the SyncAttributeTank to sync to Cronus + cv_syncTank.setAttribute(i_attr, l_type, l_pos, l_unitPos, 0, + i_size, i_pAttrData); + } + } + + // Set the real attribute void* l_pAttrData = NULL; (void) _getAttrPtr(i_attr, l_pAttrData); if (l_pAttrData) @@ -343,6 +424,98 @@ Target* Target::getTargetFromHuid( #undef TARG_FN } +//****************************************************************************** +// Target::getAttrTankTargetType() +//****************************************************************************** +uint32_t Target::getAttrTankTargetType() const +{ + // In a Targeting Attribute Tank, the Target Type is the TARGETING::TYPE + TARGETING::TYPE l_targetType = TYPE_NA; + void * l_pAttrData = NULL; + _getAttrPtr(ATTR_TYPE, l_pAttrData); + if (l_pAttrData) + { + l_targetType = *(reinterpret_cast<TARGETING::TYPE *>(l_pAttrData)); + } + + return l_targetType; +} + +//****************************************************************************** +// Target::getAttrTankTargetPos() +//****************************************************************************** +uint16_t Target::getAttrTankTargetPos() const +{ + // In a Targeting Attribute Tank, the Position for units is the + // ATTR_POSITION of the parent chip, else if the target has an ATTR_POSITION + // then it is that else it is ATTR_POS_NA + AttributeTraits<ATTR_POSITION>::Type l_targetPos = + AttributeTank::ATTR_POS_NA; + + TARGETING::CLASS l_targetClass = CLASS_NA; + void * l_pAttrData = NULL; + _getAttrPtr(ATTR_CLASS, l_pAttrData); + if (l_pAttrData) + { + l_targetClass = *(reinterpret_cast<TARGETING::CLASS *>(l_pAttrData)); + } + + if (l_targetClass == CLASS_UNIT) + { + // The position is the parent chip's position + const Target * l_pParent = getParentChip(this); + + if (l_pParent) + { + l_pParent->_getAttrPtr(ATTR_POSITION, l_pAttrData); + if (l_pAttrData) + { + l_targetPos = *(reinterpret_cast + <AttributeTraits<ATTR_POSITION>::Type *>(l_pAttrData)); + } + } + } + else + { + // The position is this object's position + _getAttrPtr(ATTR_POSITION, l_pAttrData); + if (l_pAttrData) + { + l_targetPos = *(reinterpret_cast + <AttributeTraits<ATTR_POSITION>::Type *>(l_pAttrData)); + } + } + + return l_targetPos; +} + +//****************************************************************************** +// Target::getAttrTankTargetUnitPos() +//****************************************************************************** +uint8_t Target::getAttrTankTargetUnitPos() const +{ + // In a Targeting Attribute Tank, the Unit Position for units is + // ATTR_CHIP_UNIT, else it is ATTR_UNIT_POS_NA + AttributeTraits<ATTR_CHIP_UNIT>::Type l_targetUnitPos = + AttributeTank::ATTR_UNIT_POS_NA; + + void * l_pAttrData = NULL; + _getAttrPtr(ATTR_CHIP_UNIT, l_pAttrData); + if (l_pAttrData) + { + l_targetUnitPos = *(reinterpret_cast + <AttributeTraits<ATTR_CHIP_UNIT>::Type *>(l_pAttrData)); + } + + return l_targetUnitPos; +} + +//****************************************************************************** +// Attribute Tanks +//****************************************************************************** +AttributeTank Target::cv_overrideTank; +AttributeTank Target::cv_syncTank; + #undef TARG_CLASS #undef TARG_NAMESPACE diff --git a/src/usr/targeting/common/xmltohb/xmltohb.pl b/src/usr/targeting/common/xmltohb/xmltohb.pl index 70340cbfb..994d3e855 100755 --- a/src/usr/targeting/common/xmltohb/xmltohb.pl +++ b/src/usr/targeting/common/xmltohb/xmltohb.pl @@ -249,6 +249,12 @@ if( !($cfgSrcOutputDir =~ "none") ) writeTargetErrlHFile($attributes,$targetErrlHFile); close $targetErrlHFile; + open(ATTR_INFO_CSV_FILE,">$cfgSrcOutputDir"."targAttrInfo.csv") + or fatal ("Attribute info csv file: \"$cfgSrcOutputDir" + . "targAttrInfo.csv\" could not be opened."); + my $attrInfoCsvFile = *ATTR_INFO_CSV_FILE; + writeAttrInfoCsvFile($attributes,$attrInfoCsvFile); + close $attrInfoCsvFile; } if( !($cfgImgOutputDir =~ "none") ) @@ -2138,6 +2144,85 @@ sub writeAttrErrlHFile { } # sub writeAttrErrlHFile ###### +#Create a .csv file to parse attribute overrides/syncs +##### +sub writeAttrInfoCsvFile { + my($attributes,$outFile) = @_; + + # Print the file header + print $outFile "# targAttrInfo.cvs\n"; + print $outFile "# This file is generated by perl script xmltohb.pl\n"; + print $outFile "# It lists information about TARG attributes and is used to\n"; + print $outFile "# process FAPI Attribute text files (overrides/syncs)\n"; + print $outFile "# Format:\n"; + print $outFile "# <FAPI-ATTR-ID-STR>,<LAYER-ATTR-ID-STR>,<ATTR-ID-VAL>,<ATTR-TYPE>\n"; + + my $attributeIdEnum = getAttributeIdEnumeration($attributes); + + # loop through every attribute + foreach my $attribute (@{$attributes->{attribute}}) + { + # Only (initially) support attributes with simple integer types + if ((exists $attribute->{simpleType}) && + ((exists $attribute->{simpleType}->{uint8_t}) || + (exists $attribute->{simpleType}->{uint16_t}) || + (exists $attribute->{simpleType}->{uint32_t}) || + (exists $attribute->{simpleType}->{uint64_t}))) + { + my $fapiId = "NO-FAPI-ID"; + + if (exists $attribute->{hwpfToHbAttrMap}[0]) + { + $fapiId = $attribute->{hwpfToHbAttrMap}[0]->{id}; + } + + foreach my $enum (@{$attributeIdEnum->{enumerator}}) + { + if ($enum->{name} eq $attribute->{id}) + { + print $outFile "$fapiId,"; + print $outFile "ATTR_$attribute->{id}"; + print $outFile ",$enum->{value},"; + + if (exists $attribute->{simpleType}->{uint8_t}) + { + print $outFile "u8"; + } + elsif (exists $attribute->{simpleType}->{uint16_t}) + { + print $outFile "u16"; + } + elsif (exists $attribute->{simpleType}->{uint32_t}) + { + print $outFile "u32"; + } + elsif (exists $attribute->{simpleType}->{uint64_t}) + { + print $outFile "u64"; + } + + if (exists $attribute->{simpleType}->{array}) + { + # Remove leading whitespace + my $dimText = $attribute->{simpleType}->{array}; + $dimText =~ s/^\s+//; + + # Split on commas or whitespace + my @vals = split(/\s*,\s*|\s+/, $dimText); + + foreach my $val (@vals) + { + print $outFile "[$val]"; + } + } + print $outFile "\n"; + } + } + } + } +} # sub writeAttrInfoCsvFile + +###### #Create a .C file to put target into the errlog ##### sub writeTargetErrlCFile { diff --git a/src/usr/targeting/test/makefile b/src/usr/targeting/test/makefile index 018effea2..6d8d3d1e1 100644 --- a/src/usr/targeting/test/makefile +++ b/src/usr/targeting/test/makefile @@ -1,25 +1,25 @@ -# IBM_PROLOG_BEGIN_TAG -# This is an automatically generated prolog. +# IBM_PROLOG_BEGIN_TAG +# This is an automatically generated prolog. # -# $Source: src/usr/targeting/test/makefile $ +# $Source: src/usr/targeting/test/makefile $ # -# IBM CONFIDENTIAL +# IBM CONFIDENTIAL # -# COPYRIGHT International Business Machines Corp. 2011-2012 +# COPYRIGHT International Business Machines Corp. 2011,2013 # -# p1 +# p1 # -# Object Code Only (OCO) source materials -# Licensed Internal Code Source Materials -# IBM HostBoot Licensed Internal Code +# Object Code Only (OCO) source materials +# Licensed Internal Code Source Materials +# IBM HostBoot Licensed Internal Code # -# The source code for this program is not published or other- -# wise divested of its trade secrets, irrespective of what has -# been deposited with the U.S. Copyright Office. +# 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. # -# Origin: 30 +# Origin: 30 # -# IBM_PROLOG_END_TAG +# IBM_PROLOG_END_TAG ################################################################################ # # @file src/usr/targeting/test/makefile @@ -62,7 +62,7 @@ MODULE = testtargeting COMMON_TESTCASE_REL_PATHS = \ $(addprefix ${COMMON_TARGETING_REL_PATH}/test/,${COMMON_TESTCASES}) -TESTS = testtargeting.H testattrsync.H ${COMMON_TESTCASE_REL_PATHS} +TESTS = testtargeting.H testattrsync.H testattrtank.H ${COMMON_TESTCASE_REL_PATHS} OBJS = attributestrings.o diff --git a/src/usr/targeting/test/testattrtank.H b/src/usr/targeting/test/testattrtank.H new file mode 100644 index 000000000..47187d4ca --- /dev/null +++ b/src/usr/targeting/test/testattrtank.H @@ -0,0 +1,744 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/usr/targeting/test/testattrtank.H $ */ +/* */ +/* IBM CONFIDENTIAL */ +/* */ +/* COPYRIGHT International Business Machines Corp. 2013 */ +/* */ +/* p1 */ +/* */ +/* Object Code Only (OCO) source materials */ +/* Licensed Internal Code Source Materials */ +/* IBM HostBoot Licensed Internal Code */ +/* */ +/* 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. */ +/* */ +/* Origin: 30 */ +/* */ +/* IBM_PROLOG_END_TAG */ +#ifndef TESTATTRTANK_H +#define TESTATTRTANK_H + +/** + * @file testattrtank.H + * + * @brief Test case for AttributeTank +*/ + +#include <cxxtest/TestSuite.H> + +#include <targeting/common/attributeTank.H> + +using namespace TARGETING; + +class AttrTankTest: public CxxTest::TestSuite +{ +public: + + //************************************************************************** + // tankTest1. Test AttributeTank functions with empty tank + //************************************************************************** + void tankTest1(void) + { + do + { + // Create a local AttributeTank + AttributeTank l_tank; + + // Check that tank is empty + if (l_tank.attributesExist()) + { + TS_FAIL("tankTest1: Error. AttributeTank is not empty (1)"); + break; + } + + if (l_tank.attributeExists(5)) + { + TS_FAIL("tankTest1: Error. AttributeTank is not empty (2)"); + break; + } + + // Clear all attributes from empty tank + l_tank.clearAllAttributes(); + + // Clear a non-const attribute from empty tank + l_tank.clearNonConstAttribute(ATTR_SCRATCH_UINT64_1, + TYPE_SYS, + AttributeTank::ATTR_POS_NA, + AttributeTank::ATTR_UNIT_POS_NA); + + // Try to get an attribute from empty tank + uint64_t l_val = 0; + if (l_tank.getAttribute(ATTR_SCRATCH_UINT64_1, + TYPE_SYS, + AttributeTank::ATTR_POS_NA, + AttributeTank::ATTR_UNIT_POS_NA, + &l_val)) + { + TS_FAIL("tankTest1: Error. Got attr from empty tank (3)"); + break; + } + + // Try to serialize all attributes from empty tank + std::vector<AttributeTank::AttributeSerializedChunk> l_attributes; + l_tank.serializeAttributes(AttributeTank::ALLOC_TYPE_MALLOC, + 4096, l_attributes); + + if (l_attributes.size()) + { + TS_FAIL("tankTest1: Error. Got attrs from empty tank (4)"); + break; + } + + } while (0); + + TS_TRACE("tankTest1 complete" ); + } + + //************************************************************************** + // tankTest2. Test AttributeTank functions with single attribute in tank + //************************************************************************** + void test2(void) + { + do + { + // Create a local AttributeTank + AttributeTank l_tank; + + // Add ATTR_SCRATCH_UINT64_1 to the tank + uint64_t l_val = 4; + l_tank.setAttribute(ATTR_SCRATCH_UINT64_1, + TYPE_SYS, + AttributeTank::ATTR_POS_NA, + AttributeTank::ATTR_UNIT_POS_NA, + 0, sizeof(l_val), &l_val); + + // Check that attributes exist in the tank + if (!l_tank.attributesExist()) + { + TS_FAIL("tankTest2: Error. AttributeTank is empty (1)"); + break; + } + + if (!l_tank.attributeExists(ATTR_SCRATCH_UINT64_1)) + { + TS_FAIL("tankTest2: Error. Attribute not in tank (2)"); + break; + } + + if (l_tank.attributeExists(1)) + { + TS_FAIL("tankTest2: Error. Wrong attribute in tank (3)"); + break; + } + + // Try to get the wrong attribute from the tank (wrong att ID) + l_val = 0; + if (l_tank.getAttribute(ATTR_SCRATCH_UINT64_2, + TYPE_SYS, + AttributeTank::ATTR_POS_NA, + AttributeTank::ATTR_UNIT_POS_NA, + &l_val)) + { + TS_FAIL("tankTest2: Error. Got wrong attr from tank (4)"); + break; + } + + // Try to get the wrong attribute from the tank (wrong target type) + l_val = 0; + if (l_tank.getAttribute(ATTR_SCRATCH_UINT64_1, + TYPE_PROC, + AttributeTank::ATTR_POS_NA, + AttributeTank::ATTR_UNIT_POS_NA, + &l_val)) + { + TS_FAIL("tankTest2: Error. Got wrong attr from tank (5)"); + break; + } + + // Get the attribute from the tank + l_val = 0; + if (!(l_tank.getAttribute(ATTR_SCRATCH_UINT64_1, + TYPE_SYS, + AttributeTank::ATTR_POS_NA, + AttributeTank::ATTR_UNIT_POS_NA, + &l_val))) + { + TS_FAIL("tankTest2: Error. Did not get attr from tank (6)"); + break; + } + + if (l_val != 4) + { + TS_FAIL( + "tankTest2: Error. Got bad value (0x%llx) from tank (7)", + l_val); + break; + } + + // Get the attribute from the tank using a real position + // This should succeed because attribute in tank matches all positions + l_val = 0; + if (!(l_tank.getAttribute(ATTR_SCRATCH_UINT64_1, + TYPE_SYS, + 1, + AttributeTank::ATTR_UNIT_POS_NA, + &l_val))) + { + TS_FAIL("tankTest2: Error. Did not get attr from tank (8)"); + break; + } + + if (l_val != 4) + { + TS_FAIL("tankTest2: Error. Got bad value (0x%llx) from tank (9)", + l_val); + break; + } + + // Get the attribute from the tank using a real unit-position + // This should succeed because attribute in tank matches all unit + // positions + l_val = 0; + if (!(l_tank.getAttribute(ATTR_SCRATCH_UINT64_1, + TYPE_SYS, + AttributeTank::ATTR_POS_NA, + 2, + &l_val))) + { + TS_FAIL("tankTest2: Error. Did not get attr from tank (10)"); + break; + } + + if (l_val != 4) + { + TS_FAIL("tankTest2: Error. Got bad value (0x%llx) from tank (11)", + l_val); + break; + } + + // Serialize all attributes from the tank + std::vector<AttributeTank::AttributeSerializedChunk> l_attributes; + l_tank.serializeAttributes(AttributeTank::ALLOC_TYPE_NEW, + 4096, l_attributes); + + if (l_attributes.size() != 1) + { + TS_FAIL( + "tankTest2: Error. Got wrong number of chunks (%d) from tank (12)", + l_attributes.size()); + break; + } + + if (l_attributes[0].iv_size != + (sizeof(AttributeTank::AttributeHeader) + sizeof(l_val))) + { + TS_FAIL( + "tankTest2: Error. Got wrong size (%d) of attrs from tank (13)", + l_attributes[0].iv_size); + break; + } + + uint64_t * l_pVal = reinterpret_cast<uint64_t *> + (l_attributes[0].iv_pAttributes + + sizeof(AttributeTank::AttributeHeader)); + + if (*l_pVal != 4) + { + TS_FAIL( + "tankTest2: Error. Got bad value (0x%016llx) from tank (14)", + *l_pVal); + break; + } + + // Clear the tank and check it was cleared + l_tank.clearAllAttributes(); + + l_val = 0; + if (l_tank.getAttribute(ATTR_SCRATCH_UINT64_1, + TYPE_SYS, + AttributeTank::ATTR_POS_NA, + AttributeTank::ATTR_UNIT_POS_NA, + &l_val)) + { + TS_FAIL("tankTest2: Error. Got value from empty tank (15)"); + break; + } + + // Deserialize the attribute back into the tank + l_tank.deserializeAttributes(l_attributes[0]); + + // Check the attribute made it back into the tank + l_val = 0; + if (!(l_tank.getAttribute(ATTR_SCRATCH_UINT64_1, + TYPE_SYS, + AttributeTank::ATTR_POS_NA, + AttributeTank::ATTR_UNIT_POS_NA, + &l_val))) + { + TS_FAIL("tankTest2: Error. Did not get attr from tank (16)"); + break; + } + + if (l_val != 4) + { + TS_FAIL( + "tankTest2: Error. Got bad value (0x%llx) from tank (17)", + l_val); + break; + } + + // Free the memory in the attribute chunk + delete [] l_attributes[0].iv_pAttributes; + l_attributes[0].iv_pAttributes = NULL; + + } while (0); + + TS_TRACE("tankTest2 complete" ); + } + + //************************************************************************** + // tankTest3. Test AttributeTank functions with multiple attributes in tank + //************************************************************************** + void test3(void) + { + do + { + // Create a local AttributeTank + AttributeTank l_tank; + + // Add ATTR_SCRATCH_UINT64_1 as a proc chip attribute to the tank + uint64_t l_val = 4; + l_tank.setAttribute(ATTR_SCRATCH_UINT64_1, + TYPE_PROC, + 1, + AttributeTank::ATTR_UNIT_POS_NA, + 0, sizeof(l_val), &l_val); + + // Add ATTR_SCRATCH_UINT32_1 as an MBA attribute to the tank + uint32_t l_val2 = 5; + l_tank.setAttribute(ATTR_SCRATCH_UINT32_1, + TYPE_MBA, + 1, + 2, + 0, sizeof(l_val2), &l_val2); + + // Get the first attribute from the tank + l_val = 0; + if (!(l_tank.getAttribute(ATTR_SCRATCH_UINT64_1, + TYPE_PROC, + 1, + AttributeTank::ATTR_UNIT_POS_NA, + &l_val))) + { + TS_FAIL("tankTest3: Error. Did not get attr from tank (1)"); + break; + } + + if (l_val != 4) + { + TS_FAIL( + "tankTest3: Error. Got bad value (0x%016llx) from tank (2)", + l_val); + break; + } + + // Try to get the first attribute from the tank with the wrong pos + l_val = 0; + if (l_tank.getAttribute(ATTR_SCRATCH_UINT64_1, + TYPE_PROC, + 2, + AttributeTank::ATTR_UNIT_POS_NA, + &l_val)) + { + TS_FAIL("tankTest3: Error. Got wrong attr from tank (3)"); + break; + } + + // Get the second attribute from the tank + l_val2 = 0; + if (!(l_tank.getAttribute(ATTR_SCRATCH_UINT32_1, + TYPE_MBA, + 1, + 2, + &l_val2))) + { + TS_FAIL("tankTest3: Error. Did not get attr from tank (4)"); + break; + } + + if (l_val2 != 5) + { + TS_FAIL( + "tankTest3: Error. Got bad value (0x%llx) from tank (5)", + l_val); + break; + } + + // Try to get the second attribute from the tank with the wrong + // unit position + l_val2 = 0; + if (l_tank.getAttribute(ATTR_SCRATCH_UINT32_1, + TYPE_MBA, + 1, + 3, + &l_val2)) + { + TS_FAIL("tankTest3: Error. Got wrong attr from tank (6)"); + break; + } + + // Serialize all attributes from the tank into a single chunk + std::vector<AttributeTank::AttributeSerializedChunk> l_attributes; + l_tank.serializeAttributes(AttributeTank::ALLOC_TYPE_MALLOC, + 4096, l_attributes); + + if (l_attributes.size() != 1) + { + TS_FAIL( + "tankTest3: Error. Got wrong number of chunks (%d) from tank (7)", + l_attributes.size()); + break; + } + + if (l_attributes[0].iv_size != + (sizeof(AttributeTank::AttributeHeader) + sizeof(l_val) + + sizeof(AttributeTank::AttributeHeader) + sizeof(l_val2)) ) + { + TS_FAIL( + "tankTest3: Error. Got wrong size (%d) of attrs from tank (8)", + l_attributes[0].iv_size); + break; + } + + uint64_t * l_pVal = reinterpret_cast<uint64_t *> + (l_attributes[0].iv_pAttributes + + sizeof(AttributeTank::AttributeHeader)); + + if (*l_pVal != 4) + { + TS_FAIL( + "tankTest3: Error. Got bad value (0x%016llx) from tank (9)", + *l_pVal); + break; + } + + uint32_t * l_pVal2 = reinterpret_cast<uint32_t *> + (l_attributes[0].iv_pAttributes + + sizeof(AttributeTank::AttributeHeader) + + sizeof(l_val) + sizeof(AttributeTank::AttributeHeader)); + + if (*l_pVal2 != 5) + { + TS_FAIL( + "tankTest3: Error. Got bad value (0x%08x) from tank (10)", + *l_pVal2); + break; + } + + // Clear the tank + l_tank.clearAllAttributes(); + + // Deserialize the attribute back into the tank + l_tank.deserializeAttributes(l_attributes[0]); + + // Check the first attribute made it back into the tank + l_val = 0; + if (!(l_tank.getAttribute(ATTR_SCRATCH_UINT64_1, + TYPE_PROC, + 1, + AttributeTank::ATTR_UNIT_POS_NA, + &l_val))) + { + TS_FAIL("tankTest3: Error. Did not get attr from tank (11)"); + break; + } + + if (l_val != 4) + { + TS_FAIL( + "tankTest3: Error. Got bad value (0x%016llx) from tank (12)", + l_val); + break; + } + + // Check the second attribute made it back into the tank + l_val2 = 0; + if (!(l_tank.getAttribute(ATTR_SCRATCH_UINT32_1, + TYPE_MBA, + 1, + 2, + &l_val2))) + { + TS_FAIL("tankTest3: Error. Did not get attr from tank (13)"); + break; + } + + if (l_val2 != 5) + { + TS_FAIL( + "tankTest3: Error. Got bad value (0x%llx) from tank (14)", + l_val); + break; + } + + // Free the memory in the attribute chunk + free (l_attributes[0].iv_pAttributes); + l_attributes[0].iv_pAttributes = NULL; + l_attributes.clear(); + + // Serialize all attributes from the tank into a two chunks + // Use a chunk size small enough to only fit a single attribute + l_tank.serializeAttributes(AttributeTank::ALLOC_TYPE_MALLOC, + sizeof(AttributeTank::AttributeHeader) + sizeof(l_val) + 8, + l_attributes); + + if (l_attributes.size() != 2) + { + TS_FAIL( + "tankTest3: Error. Got wrong number of chunks (%d) from tank (15)", + l_attributes.size()); + break; + } + + if (l_attributes[0].iv_size != + (sizeof(AttributeTank::AttributeHeader) + sizeof(l_val))) + { + TS_FAIL( + "tankTest3: Error. Got wrong size (%d) of attrs from tank (16)", + l_attributes[0].iv_size); + break; + } + + l_pVal = reinterpret_cast<uint64_t *> + (l_attributes[0].iv_pAttributes + + sizeof(AttributeTank::AttributeHeader)); + + if (*l_pVal != 4) + { + TS_FAIL( + "tankTest3: Error. Got bad value (0x%016llx) from tank (17)", + *l_pVal); + break; + } + + if (l_attributes[1].iv_size != + (sizeof(AttributeTank::AttributeHeader) + sizeof(l_val2))) + { + TS_FAIL( + "tankTest3: Error. Got wrong size (%d) of attrs from tank (18)", + l_attributes[1].iv_size); + break; + } + + l_pVal2 = reinterpret_cast<uint32_t *> + (l_attributes[1].iv_pAttributes + + sizeof(AttributeTank::AttributeHeader)); + + if (*l_pVal2 != 5) + { + TS_FAIL( + "tankTest3: Error. Got bad value (0x%016llx) from tank (19)", + *l_pVal); + break; + } + + // Clear the tank + l_tank.clearAllAttributes(); + + // Deserialize the attributes back into the tank + l_tank.deserializeAttributes(l_attributes[0]); + l_tank.deserializeAttributes(l_attributes[1]); + + // Check the first attribute made it back into the tank + l_val = 0; + if (!(l_tank.getAttribute(ATTR_SCRATCH_UINT64_1, + TYPE_PROC, + 1, + AttributeTank::ATTR_UNIT_POS_NA, + &l_val))) + { + TS_FAIL("tankTest3: Error. Did not get attr from tank (20)"); + break; + } + + if (l_val != 4) + { + TS_FAIL( + "tankTest3: Error. Got bad value (0x%016llx) from tank (21)", + l_val); + break; + } + + // Check the second attribute made it back into the tank + l_val2 = 0; + if (!(l_tank.getAttribute(ATTR_SCRATCH_UINT32_1, + TYPE_MBA, + 1, + 2, + &l_val2))) + { + TS_FAIL("tankTest3: Error. Did not get attr from tank (22)"); + break; + } + + if (l_val2 != 5) + { + TS_FAIL( + "tankTest3: Error. Got bad value (0x%llx) from tank (23)", + l_val); + break; + } + + // Free the memory in the attribute chunks + free (l_attributes[0].iv_pAttributes); + l_attributes[0].iv_pAttributes = NULL; + free (l_attributes[1].iv_pAttributes); + l_attributes[1].iv_pAttributes = NULL; + + } while (0); + + TS_TRACE("tankTest3 complete" ); + } + + //************************************************************************** + // tankTest4. Test AttributeTank functions with a constant attribute + //************************************************************************** + void test4(void) + { + do + { + // Create a local AttributeTank (this is not the singleton) + AttributeTank l_tank; + + // Set const attribute + uint8_t l_val = 4; + l_tank.setAttribute(ATTR_SCRATCH_UINT8_1, + TYPE_SYS, + AttributeTank::ATTR_POS_NA, + AttributeTank::ATTR_UNIT_POS_NA, + AttributeTank::ATTR_FLAG_CONST, + sizeof(l_val), &l_val); + + // Try to clear the attribute, it should not be cleared + l_tank.clearNonConstAttribute(ATTR_SCRATCH_UINT8_1, + TYPE_SYS, + AttributeTank::ATTR_POS_NA, + AttributeTank::ATTR_UNIT_POS_NA); + + // Check that tank is not-empty + if (!l_tank.attributesExist()) + { + TS_FAIL("tankTest4: Error. AttributeTank is empty (1)"); + break; + } + + // Clear all attribute + l_tank.clearAllAttributes(); + + // Check that tank is empty + if (l_tank.attributesExist()) + { + TS_FAIL("tankTest4: Error. AttributeTank is not empty (2)"); + break; + } + + } while (0); + + TS_TRACE("tankTest4 complete" ); + } + + //************************************************************************** + // tankTest5. Test adding the same attribute twice to a tank + //************************************************************************** + void test5(void) + { + do + { + // Create a local AttributeTank (this is not the singleton) + AttributeTank l_tank; + + // Add ATTR_SCRATCH_UINT64_1 to the tank twice (the second one + // should replace the first + uint64_t l_val = 4; + l_tank.setAttribute(ATTR_SCRATCH_UINT64_1, + TYPE_SYS, + AttributeTank::ATTR_POS_NA, + AttributeTank::ATTR_UNIT_POS_NA, + 0, sizeof(l_val), &l_val); + + l_val = 5; + l_tank.setAttribute(ATTR_SCRATCH_UINT64_1, + TYPE_SYS, + AttributeTank::ATTR_POS_NA, + AttributeTank::ATTR_UNIT_POS_NA, + 0, sizeof(l_val), &l_val); + + // Get the attribute from the tank + l_val = 0; + if (!(l_tank.getAttribute(ATTR_SCRATCH_UINT64_1, + TYPE_SYS, + AttributeTank::ATTR_POS_NA, + AttributeTank::ATTR_UNIT_POS_NA, + &l_val))) + { + TS_FAIL("tankTest5: Error. Did not get attr from tank (1)"); + break; + } + + if (l_val != 5) + { + TS_FAIL( + "tankTest5: Error. Got bad value (0x%llx) from tank (2)", + l_val); + break; + } + + // Serialize all attributes from the tank + std::vector<AttributeTank::AttributeSerializedChunk> l_attributes; + l_tank.serializeAttributes(AttributeTank::ALLOC_TYPE_NEW, + 4096, l_attributes); + + if (l_attributes.size() != 1) + { + TS_FAIL( + "tankTest5: Error. Got wrong number of chunks (%d) from tank (3)", + l_attributes.size()); + break; + } + + if (l_attributes[0].iv_size != + (sizeof(AttributeTank::AttributeHeader) + sizeof(l_val))) + { + TS_FAIL( + "tankTest5: Error. Got wrong size (%d) of attrs from tank (4)", + l_attributes[0].iv_size); + break; + } + + uint64_t * l_pVal = reinterpret_cast<uint64_t *> + (l_attributes[0].iv_pAttributes + + sizeof(AttributeTank::AttributeHeader)); + + if (*l_pVal != 5) + { + TS_FAIL( + "tankTest5: Error. Got bad value (0x%016llx) from tank (5)", + *l_pVal); + break; + } + delete [] l_attributes[0].iv_pAttributes; + l_attributes[0].iv_pAttributes = NULL; + + } while (0); + + TS_TRACE("tankTest5 complete" ); + } + +}; + +#endif |