diff options
23 files changed, 2207 insertions, 1439 deletions
diff --git a/src/build/debug/Hostboot/HwpfAttrOverride.pm b/src/build/debug/Hostboot/HwpfAttrOverride.pm index 5b3f312c6..ef595bcee 100755 --- a/src/build/debug/Hostboot/HwpfAttrOverride.pm +++ b/src/build/debug/Hostboot/HwpfAttrOverride.pm @@ -52,20 +52,19 @@ use constant TARGET_TYPE_MCS_CHIPLET => 0x00000040; use constant TARGET_TYPE_XBUS_ENDPOINT => 0x00000080; use constant TARGET_TYPE_ABUS_ENDPOINT => 0x00000100; -# From fapiAttributeOverride.H +# From fapiAttributeTank.H use constant ATTR_POS_NA => 0xffff; use constant ATTR_UNIT_POS_NA => 0xff; use constant ATTR_ARRAYD_NA => 0xff; -use constant ATTR_OVERRIDE_CONST => 1; -use constant ATTR_OVERRIDE_NON_CONST => 2; -use constant ATTR_OVERRIDE_CLEAR_ALL => 3; +use constant ATTR_FLAG_CONST => 1; # From fapiPlatAttrOverrideDirect.C my $overrideSymbol = 'fapi::g_attrOverride'; # Expected filenames -my $attributeIdFileName = 'fapiAttributeIds.H'; -my $overrideFileName = 'hwpfAttributeOverrides.txt'; +my $attributeIdsFileName = 'fapiAttributeIds.txt'; +my $attributeEnumsFileName = 'fapiAttributeEnums.txt'; +my $overrideFileName = 'OverrideAttrs.txt'; sub main { @@ -77,13 +76,20 @@ sub main } #-------------------------------------------------------------------------- - # Check if the Attribute ID and Attribute Overrides files exist + # Check if the Attribute IDs/Enums and Attribute Overrides files exist #-------------------------------------------------------------------------- - my $attributeIdFile = ::getImgPath(); - $attributeIdFile = $attributeIdFile."$attributeIdFileName"; - unless (-e $attributeIdFile) + my $attributeIdsFile = ::getImgPath(); + $attributeIdsFile = $attributeIdsFile."$attributeIdsFileName"; + unless (-e $attributeIdsFile) { - die "Cannot find file $attributeIdFile"; + die "Cannot find file $attributeIdsFile"; + } + + my $attributeEnumsFile = ::getImgPath(); + $attributeEnumsFile = $attributeEnumsFile."$attributeEnumsFileName"; + unless (-e $attributeEnumsFile) + { + die "Cannot find file $attributeEnumsFile"; } my $overrideFile = ::getImgPath(); @@ -94,35 +100,46 @@ sub main } #-------------------------------------------------------------------------- - # Process the Attribute ID file. Record the values of the Attribute IDs and - # the Attribute Enumeration Values in hashes + # Process the Attribute ID file. Record the values of the Attribute IDs in + # a hash #-------------------------------------------------------------------------- my %attributeIdVals; - my %attributeEnumVals; - open(IDFILE, "< $attributeIdFile") or die "Cannot open file $attributeIdFile"; + open(IDFILE, "< $attributeIdsFile") or die "Cannot open file $attributeIdsFile"; while (my $line = <IDFILE>) { chomp($line); - if ($line =~ /^\s+(ATTR_\S+) = 0x(\S+),/) + if ($line =~ /(ATTR_\S+) 0x(\S+)/) { # Found an attribute ID $attributeIdVals{$1} = hex $2 } + } + close(IDFILE); + + #-------------------------------------------------------------------------- + # Process the Attribute ENUM file. Record the values of the Attribute ENUMs + # in a hash + #-------------------------------------------------------------------------- + my %attributeEnumVals; + + open(ENUMFILE, "< $attributeEnumsFile") or die "Cannot open file $attributeEnumsFile"; + while (my $line = <ENUMFILE>) + { # Note that enumerated values can end with 'ULL' - elsif ($line =~ /\s+(ENUM_ATTR_\S+) = 0x([a-fA-F0-9]+)/) + if ($line =~ /(ATTR_\S+) = 0x([a-fA-F0-9]+)/) { # Found a hex attribute value enumeration $attributeEnumVals{$1} = hex $2; } - elsif ($line =~ /\s+(ENUM_ATTR_\S+) = ([0-9]+)/) + elsif ($line =~ /(ATTR_\S+) = ([0-9]+)/) { # Found a decimal attribute value enumeration $attributeEnumVals{$1} = $2; } } - close(IDFILE); + close(ENUMFILE); # Debug output if ($debug) @@ -142,31 +159,18 @@ sub main # override in arrays #-------------------------------------------------------------------------- my @attrIdString; - my @overrideVal; + my @val; my @attrId; my @targetType; my @pos; my @unitPos; - my @overrideType; + my @flags; my @arrayD1; my @arrayD2; my @arrayD3; my @arrayD4; - # Setup the initial override to be an instruction to "clear all overrides" - $attrIdString[0] = "CLEAR_ALL_OVERRIDES"; - $overrideVal[0] = 0; - $attrId[0] = 0; - $targetType[0] = 0; - $pos[0] = 0; - $unitPos[0] = 0; - $overrideType[0] = ATTR_OVERRIDE_CLEAR_ALL; - $arrayD1[0] = 0; - $arrayD2[0] = 0; - $arrayD3[0] = 0; - $arrayD4[0] = 0; - - my $numOverrides = 1; + my $numOverrides = 0; my $curTargetType = TARGET_TYPE_SYSTEM; my $curPos = ATTR_POS_NA; my $curUnitPos = ATTR_UNIT_POS_NA; @@ -275,7 +279,7 @@ sub main } else { - ::userDisplay "Cannot find ID $1 in $attributeIdFile\n"; + ::userDisplay "Cannot find ID $1 in $attributeIdsFile\n"; die; } @@ -322,29 +326,29 @@ sub main } # Figure out the override value - if ($line =~ /^ATTR_\S+\s+\S+\s+([A-Za-z]+\S*)/) + if ($line =~ /^ATTR_\S+\s+([A-Za-z]+\S*)/) { # enumerator - my $enum = "ENUM_"."$attrIdString[$numOverrides]"."_$1"; + my $enum = "$attrIdString[$numOverrides]"."_$1"; if (exists $attributeEnumVals{$enum}) { - $overrideVal[$numOverrides] = $attributeEnumVals{$enum}; + $val[$numOverrides] = $attributeEnumVals{$enum}; } else { - ::userDisplay "Cannot find enum $enum in $attributeIdFile\n"; + ::userDisplay "Cannot find enum $enum in $attributeEnumsFile\n"; die; } } - elsif ($line =~ /^ATTR_\S+\s+\S+\s+0x([0-9A-Za-z]+)/) + elsif ($line =~ /^ATTR_\S+\s+0x([0-9A-Za-z]+)/) { # Hex value - $overrideVal[$numOverrides] = hex $1; + $val[$numOverrides] = hex $1; } - elsif ($line =~ /^ATTR_\S+\s+\S+\s+(\d+)/) + elsif ($line =~ /^ATTR_\S+\s+(\d+)/) { # Decimal Value - $overrideVal[$numOverrides] = $1; + $val[$numOverrides] = $1; } else { @@ -352,24 +356,24 @@ sub main die; } - # Figure out the override type + # Figure out if it is a const override if ($line =~ /CONST\s*/) { - $overrideType[$numOverrides] = ATTR_OVERRIDE_CONST; + $flags[$numOverrides] = ATTR_FLAG_CONST; } else { - $overrideType[$numOverrides] = ATTR_OVERRIDE_NON_CONST; + $flags[$numOverrides] = 0; } # Debug output if ($debug) { - ::userDisplay "OVERRIDE. Val: $overrideVal[$numOverrides]. "; + ::userDisplay "OVERRIDE. Val: $val[$numOverrides]. "; ::userDisplay "ID: $attrId[$numOverrides]. "; ::userDisplay "TargType: $targetType[$numOverrides]. "; ::userDisplay "Pos: $pos[$numOverrides].$unitPos[$numOverrides].\n"; - ::userDisplay " OType: $overrideType[$numOverrides]. "; + ::userDisplay " OFlags: $flags[$numOverrides]. "; ::userDisplay "Dims: $arrayD1[$numOverrides]."; ::userDisplay "$arrayD2[$numOverrides]."; ::userDisplay "$arrayD3[$numOverrides]."; @@ -404,17 +408,17 @@ sub main # From fapiAttributeOverride.H # struct AttributeOverride # { - # uint64_t iv_overrideVal; // 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_overrideType; // fapi::AttributeOverrideType 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 + # 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 # }; #-------------------------------------------------------------------------- @@ -424,7 +428,7 @@ sub main { # Write override to Hostboot my $addr = $overrideAddr; - ::write64($addr, $overrideVal[$i]); + ::write64($addr, $val[$i]); $addr += 8; ::write32($addr, $attrId[$i]); $addr += 4; @@ -434,7 +438,7 @@ sub main $addr += 2; ::write8($addr, $unitPos[$i]); $addr++; - ::write8($addr, $overrideType[$i]); + ::write8($addr, $flags[$i]); $addr++; ::write8($addr, $arrayD1[$i]); $addr++; @@ -447,7 +451,7 @@ sub main # Tell Hostboot to process the override my $callFuncForce = 0; my @callFuncParms; - Hostboot::CallFunc::execFunc("fapi::platAttrOverrideDirect()", + Hostboot::CallFunc::execFunc("fapi::attrOverrideSync::directOverride()", $debug, $callFuncForce, \@callFuncParms); if ($debug) @@ -456,9 +460,7 @@ sub main } } - # The first override is actually an instruction to clear all overrides - my $actualNum = $numOverrides - 1; - ::userDisplay "All $actualNum override(s) successfully sent to Hostboot\n"; + ::userDisplay "All $numOverrides override(s) successfully sent to Hostboot\n"; } sub helpInfo @@ -469,8 +471,9 @@ sub helpInfo options => { "debug" => ["More debug output."], }, - notes => ["Looks for two files in the image directory", - "$attributeIdFileName: Contains attribute id/enum values", + notes => ["Looks for three files in the image directory", + "$attributeIdsFileName: Contains attribute id values", + "$attributeEnumsFileName: Contains attribute enum values", "$overrideFileName: Contains the attribute overrides"] ); } diff --git a/src/build/mkrules/dist_targets.mk b/src/build/mkrules/dist_targets.mk index 5b0bccc72..74f719ef9 100644 --- a/src/build/mkrules/dist_targets.mk +++ b/src/build/mkrules/dist_targets.mk @@ -60,7 +60,8 @@ COPY_FILES = \ img/isteplist.csv:tools,vpo \ img/dimmspd.dat:vpo \ img/procmvpd.dat:vpo \ - obj/genfiles/fapiAttributeIds.H:vpo \ + obj/genfiles/fapiAttributeIds.txt:vpo \ + obj/genfiles/fapiAttributeEnums.txt: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)\ @@ -149,7 +150,8 @@ simics.tar_CONTENTS = \ src/build/simics/hb-pnor-vpd-preload.pl \ img/dimmspd.dat \ img/procmvpd.dat \ - obj/genfiles/fapiAttributeIds.H \ + obj/genfiles/fapiAttributeIds.txt \ + obj/genfiles/fapiAttributeEnums.txt \ # # Contents for the fsp.tar. @@ -164,6 +166,8 @@ fsp.tar_CONTENTS = \ img/simics_MURANO_targeting.bin \ img/simics_VENICE_targeting.bin \ img/TULETA_targeting.bin \ + obj/genfiles/fapiAttributeIds.txt \ + obj/genfiles/fapiAttributeEnums.txt \ $(addsuffix :targeting/,\ $(call ROOTPATH_WILDCARD_RECURSIVE,src/usr/targeting/common))\ $(addsuffix :targeting/,\ diff --git a/src/include/usr/hwpf/fapi/fapiAttributeOverride.H b/src/include/usr/hwpf/fapi/fapiAttributeOverride.H deleted file mode 100644 index 2a125a5ec..000000000 --- a/src/include/usr/hwpf/fapi/fapiAttributeOverride.H +++ /dev/null @@ -1,207 +0,0 @@ -/* IBM_PROLOG_BEGIN_TAG - * This is an automatically generated prolog. - * - * $Source: src/include/usr/hwpf/fapi/fapiAttributeOverride.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 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 - */ -/** - * @file fapiAttributeOverride.H - * - * @brief Defines the AttributeOverrides and AttributeOverride classes. A - * platform can choose to use an AttributeOverrides object to store - * Attribute Overrides. - */ - -/* - * Change Log ****************************************************************** - * Flag Defect/Feature User Date Description - * ------ -------------- ---------- ----------- ---------------------------- - * mjjones 06/07/2012 Created - */ - -#ifndef FAPIATTROVERRIDE_H_ -#define FAPIATTROVERRIDE_H_ - -#include <stdint.h> -#include <list> -#include <fapiAttributeIds.H> -#include <fapiTarget.H> - -namespace fapi -{ - -/** - * @enum AttributeOverrideType - * - * Enumeration of the possible attribute override types - */ -enum AttributeOverrideType -{ - ATTR_OVERRIDE_CONST = 1, // Not cleared by a FAPI_ATTR_SET - ATTR_OVERRIDE_NON_CONST = 2, // Cleared by a FAPI_ATTR_SET - ATTR_OVERRIDE_CLEAR_ALL = 3, // Clear all overrides -}; - -// Constants for various fields in AttributeOverrides -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_arayX not applicable - -/** - * @struct AttributeOverride - * - * This structure defines a single attribute override. In the case of an array - * attribute, it is an override for a single element - */ -struct AttributeOverride -{ - uint64_t iv_overrideVal; // 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_overrideType; // fapi::AttributeOverrideType 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 -}; - -/** - * @class AttributeOverrides - * - * This class can be used to set and query attribute overrides - */ -class AttributeOverrides -{ -public: - /** - * @brief Default constructor - */ - AttributeOverrides(); - - /** - * @brief Destructor - */ - ~AttributeOverrides(); - - /** - * @brief Clear all overrides - */ - void clearOverrides(); - - /** - * @brief Clear any non-const override for a specified ID and Target - * - * @param[in] i_attrId Attribute ID - * @param[in] i_pTarget Pointer to Target (NULL if system) - */ - void clearNonConstOverride(const fapi::AttributeId i_attrId, - const fapi::Target * const i_pTarget); - - /** - * @brief Set an override - * - * Note that no checking is done for duplicate overrides (an override on an - * attribute that already has an override) for performance. If a duplicate - * override is done then getOverride will return the first one. - * - * @param[in] i_override Reference to override structure, this is copied - */ - void setOverride(const AttributeOverride & i_override); - - /** - * @brief Get an override - * - * Note that for array attributes, this must be called repeatedly, to query - * an override for each element of the array - * - * @param[in] i_attrId Attribute ID - * @param[in] i_pTarget Pointer to Target (NULL if system) - * @param[out] o_overrideVal Reference that is filled in with the override - * @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 override exists and was returned. - */ - bool getOverride(const fapi::AttributeId i_attrId, - const fapi::Target * const i_pTarget, - uint64_t & o_overrideVal, - 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 Returns if any overrides exist - * - * This is only expected to be called by unit test - * - * return true if any overrides exist - */ - bool overridesExist(); - -private: - // Copy constructor and assignment operator disabled - AttributeOverrides(const AttributeOverrides & i_right); - AttributeOverrides & operator=(const AttributeOverrides & i_right); - - /** - * @brief Returns if the specified override is for the specified - * attribute ID and Target - * - * @param[in] i_attrId Attribute ID - * @param[in] i_pTarget Pointer to Target (NULL if system) - * @param[in] i_candidate Reference to AttributeOverride - * - * @return true if the AttributeOverride matches - */ - static bool overrideMatch(const fapi::AttributeId i_attrId, - const fapi::Target * const i_pTarget, - const AttributeOverride & i_candidate); - - /** - * @brief Locks the AttributeOverrides object - * - * Implemented by the platform - */ - static void platLock(); - - /** - * @brief Unlocks the AttributeOverrides object - * - * Implemented by the platform - */ - static void platUnlock(); - - // The attribute overrides - bool iv_overridesExist; - std::list<AttributeOverride *> iv_overrides; - typedef std::list<AttributeOverride *>::iterator OverridesItr_t; - typedef std::list<AttributeOverride *>::const_iterator OverridesCItr_t; - -}; - -} - -#endif // FAPIATTROVERRIDE_H_ diff --git a/src/include/usr/hwpf/fapi/fapiAttributeService.H b/src/include/usr/hwpf/fapi/fapiAttributeService.H index 1744d11a6..186a43222 100644 --- a/src/include/usr/hwpf/fapi/fapiAttributeService.H +++ b/src/include/usr/hwpf/fapi/fapiAttributeService.H @@ -1,26 +1,25 @@ -/* IBM_PROLOG_BEGIN_TAG - * This is an automatically generated prolog. - * - * $Source: src/include/usr/hwpf/fapi/fapiAttributeService.H $ - * - * 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 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/include/usr/hwpf/fapi/fapiAttributeService.H $ */ +/* */ +/* 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 fapiAttributeService.H * @@ -86,12 +85,12 @@ * <ID>_GETMACRO PLAT macro is called to get the attribute, platforms must * define a _GETMACRO for each attribute. * - * The SET macro calls the <ID>_SETMACRO PLAT macro to set the attribute, - * platforms must define a _SETMACRO for each attribute. It then calls the - * FAPI_PLAT_CLEAR_NON_CONST_ATTR_OVERRIDE to clear any non-const attribute - * overrides (platforms can set this to NULL if they do not support - * attribute override or if they handle it in the standard <ID>_SETMACRO - * path). + * 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 @@ -107,7 +106,7 @@ #define FAPI_ATTR_SET(ID, PTARGET, VAL) \ (fapi::fapiFailIfPrivileged<fapi::ID##_Privileged>(), \ fapi::fapiCheckIdType<fapi::ID##_Type>(fapi::ID, VAL), \ - FAPI_PLAT_CLEAR_NON_CONST_ATTR_OVERRIDE(fapi::ID, PTARGET), \ + FAPI_PLAT_ATTR_SET_ACTIONS(fapi::ID, PTARGET, VAL), \ ID##_SETMACRO(ID, PTARGET, VAL)) #define FAPI_ATTR_GET_PRIVILEGED(ID, PTARGET, VAL) \ @@ -118,7 +117,7 @@ #define FAPI_ATTR_SET_PRIVILEGED(ID, PTARGET, VAL) \ (fapi::fapiCheckIdType<fapi::ID##_Type>(fapi::ID, VAL), \ - FAPI_PLAT_CLEAR_NON_CONST_ATTR_OVERRIDE(fapi::ID, PTARGET), \ + 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 new file mode 100644 index 000000000..1a666e8cf --- /dev/null +++ b/src/include/usr/hwpf/fapi/fapiAttributeTank.H @@ -0,0 +1,713 @@ +/* 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 +{ + 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); + 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( + 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/hwp/fapiTestHwpAttr.H b/src/include/usr/hwpf/hwp/fapiTestHwpAttr.H index 1bb9481b6..ba28e440e 100755 --- a/src/include/usr/hwpf/hwp/fapiTestHwpAttr.H +++ b/src/include/usr/hwpf/hwp/fapiTestHwpAttr.H @@ -1,25 +1,25 @@ -// IBM_PROLOG_BEGIN_TAG -// This is an automatically generated prolog. -// -// $Source: src/include/usr/hwpf/hwp/fapiTestHwpAttr.H $ -// -// IBM CONFIDENTIAL -// -// COPYRIGHT International Business Machines Corp. 2011 -// -// 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 +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/include/usr/hwpf/hwp/fapiTestHwpAttr.H $ */ +/* */ +/* 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.H * @@ -48,9 +48,12 @@ extern "C" /** * @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::ReturnCode hwpTestAttributes(fapi::Target & i_mbaTarget, + fapi::Target & i_procTarget); } diff --git a/src/include/usr/hwpf/plat/fapiPlatAttrOverrideSync.H b/src/include/usr/hwpf/plat/fapiPlatAttrOverrideSync.H new file mode 100755 index 000000000..ab2a5ee3d --- /dev/null +++ b/src/include/usr/hwpf/plat/fapiPlatAttrOverrideSync.H @@ -0,0 +1,94 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/include/usr/hwpf/plat/fapiPlatAttrOverrideSync.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 fapiPlatAttrOverrdieSync.H + * + * @brief Defines the functions for Attribute Override and Sync + */ + +#ifndef FAPIPLATATTROVERRIDESYNC_H_ +#define FAPIPLATATTROVERRIDESYNC_H_ + +//****************************************************************************** +// Includes +//****************************************************************************** +#include <stdint.h> +#include <hwpf/fapi/fapiAttributeTank.H> + +//****************************************************************************** +// Interface +//****************************************************************************** +namespace fapi +{ + +namespace attrOverrideSync +{ + +/** + * @brief Monitors for incoming messages from the FSP. This 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. 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<> + */ +AttributeTank & theOverrideAttrTank(); + +/** + * @brief This function returns the SyncAttributeTank singleton. Other + * modules must call this rather than using Singleton<> + */ +AttributeTank & theSyncAttrTank(); + +} // namespace attrOverrideSync + +} // namespace fapi + +/** + * @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 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) + +#endif // FAPIPLATATTROVERRIDESYNC_H_ diff --git a/src/include/usr/hwpf/plat/fapiPlatAttributeService.H b/src/include/usr/hwpf/plat/fapiPlatAttributeService.H index ec91f615d..bbd926656 100755 --- a/src/include/usr/hwpf/plat/fapiPlatAttributeService.H +++ b/src/include/usr/hwpf/plat/fapiPlatAttributeService.H @@ -23,8 +23,8 @@ /** * @file fapiPlatAttributeService.H * - * @brief Defines the PLAT attribute access macros and defines which macro - * handles each attribute. + * @brief Defines the PLAT attribute access macros and the functions that + * access attributes * * Note that platform code must provide the code. */ @@ -51,7 +51,8 @@ #include <fapiplatattrmacros.H> #include <hwpf/fapi/fapiReturnCode.H> #include <hwpf/fapi/fapiTarget.H> -#include <hwpf/fapi/fapiAttributeOverride.H> +#include <hwpf/fapi/fapiAttributeTank.H> +#include <hwpf/plat/fapiPlatAttrOverrideSync.H> #include <spd/spdenums.H> #include <dimmConsts.H> #include <util/singleton.H> @@ -201,260 +202,6 @@ fapi::ReturnCode fapiPlatGetFunctional(const fapi::Target * i_pTarget, fapi::ReturnCode fapiPlatGetTargetPos(const fapi::Target * i_pFapiTarget, uint32_t & o_pos); -/** - * @brief This wrapper function is called by the getAttrOverride function - * templates (which are called by FAPI_PLAT_GET_ATTR_OVERRIDE) to get an - * attribute override value - * - * This wrapper just invokes getAttrOverride on the AttributeOverrides singleton - * in the local (plat) module, it is needed because Singletons cannot be - * accessed outside of a module (this results in a duplicate singleton) - * - * @param[in] i_attrId Attribute ID - * @param[in] i_pTarget Pointer to Target (NULL if system) - * @param[out] o_overrideVal Reference to value filled in with the override - * @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 bool True if override value was returned - */ -bool getOverrideWrap(const fapi::AttributeId i_attrId, - const fapi::Target * const i_pTarget, - uint64_t & o_overrideVal, - 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 This wrapper function is called by - * FAPI_PLAT_CLEAR_NON_CONST_ATTR_OVERRIDE to clear a non-const attribute - * override. - * - * This wrapper just invokes clearNonConstOverride on the AttributeOverrides - * singleton in the local (plat) module, it is needed because Singletons cannot - * be accessed outside of a module (this results in a duplicate singleton) - * - * @param[in] i_attrId Attribute ID - * @param[in] i_pTarget Pointer to Target (NULL if system) - */ -void clearNonConstOverrideWrap(const fapi::AttributeId i_attrId, - const fapi::Target * const i_pTarget); - -/** - * @brief This wrapper function is called by HWP unit test to set an attribute - * override. It is not called by production code (outside of unit test, - * attribute overrides are set by the FSP or by a debug tool) - * - * This wrapper just invokes setOverride on the AttributeOverrides singleton in - * the local (plat) module, it is needed because Singletons cannot be accessed - * outside of a module (this results in a duplicate singleton) - * - * @param[in] i_override Reference to override - */ -void setOverrideWrap(const AttributeOverride & i_override); - -/** - * @brief This wrapper function is called by HWP unit test to clear all - * attribute overrides. It is not called by production code (outside of - * unit test, attribute overrides are cleared by the FSP or by a debug - * tool) - * - * This wrapper just invokes clearOverrides on the AttributeOverrides singleton - * in the local (plat) module, it is needed because Singletons cannot be - * accessed outside of a module (this results in a duplicate singleton) - */ -void clearOverridesWrap(); - -/** - * @brief This wrapper function is called by HWP unit test to test if any - * attribute overrides exist. It is not called by production code. - * - * This wrapper just invokes overridesExist on the AttributeOverrides singleton - * in the local (plat) module, it is needed because Singletons cannot be - * accessed outside of a module (this results in a duplicate singleton) - */ -bool overridesExistWrap(); - -/** - * @brief This function template is called by the FAPI_PLAT_GET_ATTR_OVERRIDE - * macro to get any override for a 1D array attribute - * - * @param[in] i_attrId Attribute ID - * @param[in] i_pTarget Pointer to Target (NULL if system) - * @param[out] o_1dArray Reference to 1D array where override will be copied to - * @return bool True if override was returned - */ -template <typename T, uint8_t SZ1> -bool getOverrideT(const fapi::AttributeId i_attrId, - const fapi::Target * const i_pTarget, - T(&o_1dArray)[SZ1]) -{ - uint64_t l_overrideVal = 0; - - for (uint8_t d1 = 0; d1 < SZ1; d1++) - { - if (!(getOverrideWrap(i_attrId, i_pTarget, l_overrideVal, d1))) - { - // For array attributes, all elements must be overridden - return false; - } - else - { - // Standard conversion converts uint64_t to attribute type - o_1dArray[d1] = l_overrideVal; - } - } - - return true; -} - -/** - * @brief This function template is called by the FAPI_PLAT_GET_ATTR_OVERRIDE - * macro to get any override for a 2D array attribute - * - * @param[in] i_attrId Attribute ID - * @param[in] i_pTarget Pointer to Target (NULL if system) - * @param[out] o_2dArray Reference to 2D array where override will be copied to - * @return bool True if override was returned - */ -template <typename T, uint8_t SZ1, uint8_t SZ2> -bool getOverrideT(const fapi::AttributeId i_attrId, - const fapi::Target * const i_pTarget, - T(&o_2dArray)[SZ1][SZ2]) -{ - uint64_t l_overrideVal = 0; - - for (uint8_t d1 = 0; d1 < SZ1; d1++) - { - for (uint8_t d2 = 0; d2 < SZ2; d2++) - { - if (!(getOverrideWrap(i_attrId, i_pTarget, l_overrideVal, 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_overrideVal; - } - } - } - - return true; -} - -/** - * @brief This function template is called by the FAPI_PLAT_GET_ATTR_OVERRIDE - * macro to get any override for a 3D array attribute - * - * @param[in] i_attrId Attribute ID - * @param[in] i_pTarget Pointer to Target (NULL if system) - * @param[out] o_3dArray Reference to 3D array where override will be copied to - * @return bool True if override was returned - */ -template <typename T, uint8_t SZ1, uint8_t SZ2, uint8_t SZ3> -bool getOverrideT(const fapi::AttributeId i_attrId, - const fapi::Target * const i_pTarget, - T(&o_3dArray)[SZ1][SZ2][SZ3]) -{ - uint64_t l_overrideVal = 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 (!(getOverrideWrap(i_attrId, i_pTarget, l_overrideVal, 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_overrideVal; - } - } - } - } - - return true; -} - -/** - * @brief This function template is called by the FAPI_PLAT_GET_ATTR_OVERRIDE - * macro to get any override for a 4D array attribute - * - * @param[in] i_attrId Attribute ID - * @param[in] i_pTarget Pointer to Target (NULL if system) - * @param[out] o_4dArray Reference to 4D array where override 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 getOverrideT(const fapi::AttributeId i_attrId, - const fapi::Target * const i_pTarget, - T(&o_4dArray)[SZ1][SZ2][SZ3][SZ4]) -{ - uint64_t l_overrideVal = 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 (!(getOverrideWrap(i_attrId, i_pTarget, l_overrideVal, - 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_overrideVal; - } - } - } - } - } - - return true; -} - -/** - * @brief This function template is called by the FAPI_PLAT_GET_ATTR_OVERRIDE - * macro to get any override for a non-array attribute - * - * @param[in] i_attrId Attribute ID - * @param[in] i_pTarget Pointer to Target (NULL if system) - * @param[out] o_val Reference to variable where override will be copied to - * @return bool True if override was returned - */ -template <typename T> -bool getOverrideT(const fapi::AttributeId i_attrId, - const fapi::Target * const i_pTarget, - T & o_val) -{ - uint64_t l_overrideVal = 0; - - if (!(getOverrideWrap(i_attrId, i_pTarget, l_overrideVal))) - { - return false; - } - - o_val = static_cast<T>(l_overrideVal); - return true; -} - //------------------------------------------------------------------------------ // Prototypes to support proc_setup_bars_memory_attributes // See proc_setup_bars_memory_attributes.xml for detailed descriptions @@ -656,18 +403,6 @@ fapi::ReturnCode fapiPlatGetProcPcieBarSize ( } // namespace fapi /** - * @brief Macro that returns any attribute override - */ -#define FAPI_PLAT_GET_ATTR_OVERRIDE(ID, PTARGET, VAL) \ - fapi::platAttrSvc::getOverrideT(ID, PTARGET, VAL) - -/** - * @brief Macro that clears any non-const attribute override - */ -#define FAPI_PLAT_CLEAR_NON_CONST_ATTR_OVERRIDE(ID, PTARGET) \ - fapi::platAttrSvc::clearNonConstOverrideWrap(ID, PTARGET) - -/** * @brief Macro which directly maps a FAPI request to get a platform * attribute to the equivalent host boot request */ diff --git a/src/include/usr/mbox/mbox_queues.H b/src/include/usr/mbox/mbox_queues.H index 0fba7ca30..65c5265d5 100644 --- a/src/include/usr/mbox/mbox_queues.H +++ b/src/include/usr/mbox/mbox_queues.H @@ -40,23 +40,24 @@ namespace MBOX enum queue_id_t { NOT_FOUND = 0, - HB_MAILBOX_MSGQ, - HB_ISTEP_MSGQ, - HB_ATTR_SYNC_MSGQ, - HB_ERROR_MSGQ, + HB_MAILBOX_MSGQ = 1, + HB_ISTEP_MSGQ = 2, + HB_ATTR_SYNC_MSGQ = 3, + HB_ERROR_MSGQ = 4, + HB_HWPF_ATTR_MSGQ = 5, // HWPF Attribute override/sync // Add HB services here: HB_TEST_MSGQ = 0x7FFFFFFF, // FSP mailboxes FSP_FIRST_MSGQ = 0x80000000, - FSP_MAILBOX_MSGQ, - FSP_PROGRESS_CODES_MSGQ, - FSP_TRACE_MSGQ, + FSP_MAILBOX_MSGQ = 0x80000001, + FSP_PROGRESS_CODES_MSGQ = 0x80000002, + FSP_TRACE_MSGQ = 0x80000003, FSP_ERROR_MSGQ = 0x80000004, - IPL_SERVICE_QUEUE = 0x80000008, // Defined by Fsp team + IPL_SERVICE_QUEUE = 0x80000008, // Defined by Fsp team FSP_ATTR_SYNC_MSGQ = 0x80000009, - + FSP_HWPF_ATTR_MSGQ = 0x8000000a, // HWPF Attribute override/sync // Add FSP services here: FSP_ECHO_MSGQ = 0xFFFFFFFF, // Fake FSP for test }; diff --git a/src/usr/hwpf/fapi/fapiAttributeOverride.C b/src/usr/hwpf/fapi/fapiAttributeOverride.C deleted file mode 100644 index 636bafc25..000000000 --- a/src/usr/hwpf/fapi/fapiAttributeOverride.C +++ /dev/null @@ -1,331 +0,0 @@ -/* IBM_PROLOG_BEGIN_TAG - * This is an automatically generated prolog. - * - * $Source: src/usr/hwpf/fapi/fapiAttributeOverride.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 - */ -/** - * @file fapiAttributeOverride.C - * - * @brief Implements the AttributeOverrides and AttributeOverride classes. - */ - -/* - * Change Log ****************************************************************** - * Flag Defect/Feature User Date Description - * ------ -------------- ---------- ----------- ---------------------------- - * mjjones 06/07/2012 Created - */ - -#include <fapiAttributeOverride.H> -#include <fapiAttributeService.H> -#include <fapiPlatTrace.H> -#include <fapiReturnCode.H> -#include <fapiSystemConfig.H> - -namespace fapi -{ - -//****************************************************************************** -// Default Constructor -//****************************************************************************** -AttributeOverrides::AttributeOverrides() - : iv_overridesExist(false) -{ - FAPI_IMP("AttributeOverrides: Constructor"); -} - -//****************************************************************************** -// Destructor -//****************************************************************************** -AttributeOverrides::~AttributeOverrides() -{ - FAPI_IMP("AttributeOverrides: Destructor"); - for (OverridesItr_t l_itr = iv_overrides.begin(); l_itr - != iv_overrides.end(); ++l_itr) - { - delete (*l_itr); - } -} - -//****************************************************************************** -// clearOverrides -//****************************************************************************** -void AttributeOverrides::clearOverrides() -{ - FAPI_IMP("AttributeOverrides: Clearing all overrides"); - platLock(); - - iv_overridesExist = false; - - for (OverridesItr_t l_itr = iv_overrides.begin(); l_itr - != iv_overrides.end(); ++l_itr) - { - delete (*l_itr); - } - - iv_overrides.clear(); - - platUnlock(); -} - -//****************************************************************************** -// clearNonConstOverride -//****************************************************************************** -void AttributeOverrides::clearNonConstOverride( - const fapi::AttributeId i_attrId, - const fapi::Target * const i_pTarget) -{ - // Do a quick check to see if any overrides exist. This is deliberately done - // without a lock for performance. Overrides should not be changed while - // HWPs are setting attributes, but even if they are there is no risk of - // corruption. - if (!iv_overridesExist) - { - return; - } - - platLock(); - - // Note that for an array attribute with an override, there will be multiple - // AttributeOverride objects, one for each element - OverridesItr_t l_itr = iv_overrides.begin(); - - while (l_itr != iv_overrides.end()) - { - if (((*l_itr)->iv_overrideType == ATTR_OVERRIDE_NON_CONST) && - overrideMatch(i_attrId, i_pTarget, *(*l_itr))) - { - delete (*l_itr); - l_itr = iv_overrides.erase(l_itr); - } - else - { - ++l_itr; - } - } - - if (iv_overrides.empty()) - { - iv_overridesExist = false; - } - - platUnlock(); -} - -//****************************************************************************** -// setOverride -//****************************************************************************** -void AttributeOverrides::setOverride(const AttributeOverride & i_override) -{ - if (i_override.iv_overrideType == ATTR_OVERRIDE_CLEAR_ALL) - { - clearOverrides(); - } - else - { - FAPI_IMP("Set Override. ID: 0x%x, Val: 0x%llx, Type: %d", - i_override.iv_attrId, i_override.iv_overrideVal, - i_override.iv_overrideType); - FAPI_INF("Set Override. Target Type: 0x%x, Pos: 0x%x, UPos: 0x%x", - i_override.iv_targetType, i_override.iv_pos, - i_override.iv_unitPos); - FAPI_INF("Set Override. Array Dims: %d.%d.%d.%d", - i_override.iv_arrayD1, i_override.iv_arrayD2, - i_override.iv_arrayD3, i_override.iv_arrayD4); - - AttributeOverride * l_pOverride = new AttributeOverride(); - *l_pOverride = i_override; - - platLock(); - iv_overridesExist = true; - iv_overrides.push_back(l_pOverride); - platUnlock(); - } -} - -//****************************************************************************** -// getOverride -//****************************************************************************** -bool AttributeOverrides::getOverride(const fapi::AttributeId i_attrId, - const fapi::Target * const i_pTarget, - uint64_t & o_overrideVal, - const uint8_t i_arrayD1, - const uint8_t i_arrayD2, - const uint8_t i_arrayD3, - const uint8_t i_arrayD4) -{ - // Do a quick check to see if any overrides exist. This is deliberately done - // without a lock for performance. Overrides should not be changed while - // HWPs are getting attributes, but even if they are there is no risk of - // corruption. - if (!iv_overridesExist) - { - return false; - } - - platLock(); - bool l_found = false; - - for (OverridesCItr_t l_itr = iv_overrides.begin(); l_itr - != iv_overrides.end(); ++l_itr) - { - if (overrideMatch(i_attrId, i_pTarget, *(*l_itr))) - { - // Check the array dimensions - if (((*l_itr)->iv_arrayD1 == i_arrayD1) && - ((*l_itr)->iv_arrayD2 == i_arrayD2) && - ((*l_itr)->iv_arrayD3 == i_arrayD3) && - ((*l_itr)->iv_arrayD4 == i_arrayD4)) - { - l_found = true; - o_overrideVal = (*l_itr)->iv_overrideVal; - FAPI_IMP("Returning HWPF Attribute Override, 0x%x = 0x%llx", - i_attrId, o_overrideVal); - break; - } - } - } - - platUnlock(); - return l_found; -} - -//****************************************************************************** -// overridesExist -//****************************************************************************** -bool AttributeOverrides::overridesExist() -{ - platLock(); - bool l_overridesExist = iv_overridesExist; - platUnlock(); - return l_overridesExist; -} - -//****************************************************************************** -// overrideMatch -//****************************************************************************** -bool AttributeOverrides::overrideMatch( - const fapi::AttributeId i_attrId, - const fapi::Target * const i_pTarget, - const AttributeOverride & i_candidate) -{ - // Note that any errors querying a parent chip or a position attribute are - // dropped and the function returns false (attribute is not a match) - - // Check the Attribute ID - if (i_candidate.iv_attrId != static_cast<uint32_t>(i_attrId)) - { - return false; - } - - // Check the Target Type - if (i_pTarget == NULL) - { - if (i_candidate.iv_targetType != - static_cast<uint32_t>(TARGET_TYPE_SYSTEM)) - { - return false; - } - } - else if (i_candidate.iv_targetType != - static_cast<uint32_t>(i_pTarget->getType())) - { - return false; - } - - // Check the Target position if applicable and not the system Target - if ((i_candidate.iv_pos != ATTR_POS_NA) && - (i_pTarget != NULL) && - (i_pTarget->getType() != TARGET_TYPE_SYSTEM)) - { - ReturnCode l_rc; - uint32_t l_pos = 0xffffffff; - - if (i_pTarget->isChiplet()) - { - // Target is a chiplet, iv_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)); - return false; - } - - 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)); - return false; - } - } - 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)); - return false; - } - } - - if (i_candidate.iv_pos != l_pos) - { - return false; - } - } - - // Check the Unit Target position if applicable and a unit Target - if ((i_candidate.iv_unitPos != ATTR_UNIT_POS_NA) && - (i_pTarget != NULL) && - (i_pTarget->isChiplet())) - { - ReturnCode l_rc; - uint8_t l_unitPos = 0xff; - - 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)); - return false; - } - - if (i_candidate.iv_unitPos != l_unitPos) - { - return false; - } - } - - // Match - return true; -} - -} diff --git a/src/usr/hwpf/fapi/fapiAttributeTank.C b/src/usr/hwpf/fapi/fapiAttributeTank.C new file mode 100644 index 000000000..20f5fc081 --- /dev/null +++ b/src/usr/hwpf/fapi/fapiAttributeTank.C @@ -0,0 +1,443 @@ +/* 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 +{ + +//****************************************************************************** +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( + 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 3a0ab3bea..bff32a105 100755 --- a/src/usr/hwpf/fapi/fapiParseAttributeInfo.pl +++ b/src/usr/hwpf/fapi/fapiParseAttributeInfo.pl @@ -62,6 +62,8 @@ # mjjones 06/12/12 Add new include file to fapiChipEcFeature.C # mjjones 08/08/12 Output target types and if PlatInit # mjjones 09/28/12 Minor change to add FFDC on error +# mjjones 11/05/12 Generate fapiAttributeIds.txt +# Generate fapiAttributeEnums.txt # # End Change Log ****************************************************** @@ -80,6 +82,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"); exit(1); } @@ -123,6 +127,16 @@ $asFile .= "/"; $asFile .= "fapiAttributesSupported.html"; open(ASFILE, ">", $asFile); +my $itFile = $ARGV[0]; +$itFile .= "/"; +$itFile .= "fapiAttributeIds.txt"; +open(ITFILE, ">", $itFile); + +my $etFile = $ARGV[0]; +$etFile .= "/"; +$etFile .= "fapiAttributeEnums.txt"; +open(ETFILE, ">", $etFile); + #------------------------------------------------------------------------------ # Print Start of file information to fapiAttributeIds.H #------------------------------------------------------------------------------ @@ -196,8 +210,8 @@ 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>"; -my %enumHash; -my %attrIdHash; +my %attrIdHash; # Records which Attribute IDs have been used +my %attrValHash; # Records which Attribute values have been used #------------------------------------------------------------------------------ # For each XML file @@ -219,9 +233,9 @@ foreach my $argnum (1 .. $#ARGV) foreach my $attr (@{$attributes->{attribute}}) { #---------------------------------------------------------------------- - # Print the AttributeId enum to fapiAttributeIds.H - # The enumerator value for each attribute is a hash value generated - # from the attribute name, this ties a specific enumerator value to a + # Print the Attribute ID and calculated value to fapiAttributeIds.H and + # fapiAttributeIds.txt. The value for an attribute is a hash value + # generated from the attribute name, this ties a specific value to a # specific attribute name. This is done for Cronus so that if a HWP is # not recompiled against a new eCMD/Cronus version where the attributes # have changed then there will not be a mismatch in enumerator values. @@ -248,9 +262,14 @@ foreach my $argnum (1 .. $#ARGV) # Calculate a 28 bit hash value. my $attrHash128Bit = md5_hex($attr->{id}); my $attrHash28Bit = substr($attrHash128Bit, 0, 7); + + # Print the attribute ID/value to fapiAttributeIds.H print AIFILE " $attr->{id} = 0x$attrHash28Bit,\n"; - if (exists($enumHash{$attrHash28Bit})) + # 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! print ("fapiParseAttributeInfo.pl ERROR. Duplicate attr id hash value for ", @@ -258,7 +277,7 @@ foreach my $argnum (1 .. $#ARGV) exit(1); } - $enumHash{$attrHash28Bit} = 1; + $attrValHash{$attrHash28Bit} = 1; }; } @@ -316,8 +335,6 @@ foreach my $argnum (1 .. $#ARGV) my $numArrayDimensions = 0; if ($attr->{array}) { - # Figure out the array dimensions - # Remove leading whitespace my $dimText = $attr->{array}; $dimText =~ s/^\s+//; @@ -424,7 +441,8 @@ foreach my $argnum (1 .. $#ARGV) } #---------------------------------------------------------------------- - # Print the value enumeration (if specified) to fapiAttributeIds.H + # Print the value enumeration (if specified) to fapiAttributeIds.H and + # fapiAttributeEnums.txt #---------------------------------------------------------------------- if (exists $attr->{enum}) { @@ -440,8 +458,15 @@ foreach my $argnum (1 .. $#ARGV) $val =~ s/\n//; $val =~ s/^\s+//; $val =~ s/\s+$//; + + # Print the attribute enum to fapiAttributeIds.H print AIFILE " ENUM_$attr->{id}_${val}"; + # Print the attribute enum to fapiAttributeEnums.txt + my $attrEnumTxt = "$attr->{id}_${val}\n"; + $attrEnumTxt =~ s/= //; + print ETFILE $attrEnumTxt; + if ($attr->{valueType} eq 'uint64') { print AIFILE "ULL"; @@ -630,6 +655,9 @@ print ASFILE "</html>\n"; # Close output files #------------------------------------------------------------------------------ close(AIFILE); +close(ECFILE); close(ACFILE); close(ASFILE); +close(ITFILE); +close(ETFILE); diff --git a/src/usr/hwpf/fapi/makefile b/src/usr/hwpf/fapi/makefile index ddb17b4b9..0a76de05f 100644 --- a/src/usr/hwpf/fapi/makefile +++ b/src/usr/hwpf/fapi/makefile @@ -36,7 +36,7 @@ OBJS = fapiReturnCode.o \ fapiErrorInfo.o \ fapiAttributeService.o \ fapiChipEcFeature.o \ - fapiAttributeOverride.o \ + fapiAttributeTank.o \ fapiCollectRegFfdc.o include ${ROOTPATH}/config.mk diff --git a/src/usr/hwpf/hwp/fapiTestHwp.C b/src/usr/hwpf/hwp/fapiTestHwp.C index 2d299b19b..6dc4ef853 100644 --- a/src/usr/hwpf/hwp/fapiTestHwp.C +++ b/src/usr/hwpf/hwp/fapiTestHwp.C @@ -96,7 +96,7 @@ fapi::ReturnCode hwpInitialTest(const std::vector<fapi::Target> & i_target) // -------------------------------------------------------- // 2. fapiPutScom test // -------------------------------------------------------- - uint64_t l_scomWriteValue = 0x9000000000000000; + uint64_t l_scomWriteValue = 0x9000000000000000ULL; l_ecmdRc = l_ScomData.setDoubleWord(0, l_scomWriteValue); if (l_ecmdRc != ECMD_DBUF_SUCCESS) @@ -120,8 +120,8 @@ fapi::ReturnCode hwpInitialTest(const std::vector<fapi::Target> & i_target) // -------------------------------------------------------- // 3. fapiPutScomUnderMask test // -------------------------------------------------------- - l_scomWriteValue = 0xA000000000000000; - uint64_t l_mask = 0x3000000000000000; + l_scomWriteValue = 0xA000000000000000ULL; + uint64_t l_mask = 0x3000000000000000ULL; ecmdDataBufferBase l_maskData(64); l_ecmdRc = l_ScomData.setDoubleWord(0, l_scomWriteValue); diff --git a/src/usr/hwpf/hwp/fapiTestHwpAttr.C b/src/usr/hwpf/hwp/fapiTestHwpAttr.C index bb7701595..0cee8edf5 100755 --- a/src/usr/hwpf/hwp/fapiTestHwpAttr.C +++ b/src/usr/hwpf/hwp/fapiTestHwpAttr.C @@ -42,14 +42,12 @@ * 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> -#include <targeting/common/target.H> -#include <targeting/common/commontargeting.H> -#include <targeting/common/utilFilter.H> extern "C" { @@ -57,7 +55,8 @@ extern "C" //****************************************************************************** // hwpTestAttributes function //****************************************************************************** -fapi::ReturnCode hwpTestAttributes() +fapi::ReturnCode hwpTestAttributes(fapi::Target & i_mbaTarget, + fapi::Target & i_procTarget) { FAPI_INF("hwpTestAttributes: Start HWP"); fapi::ReturnCode l_rc; @@ -65,69 +64,6 @@ fapi::ReturnCode hwpTestAttributes() do { //---------------------------------------------------------------------- - // Test ATTR_MSS_DIMM_MFG_ID_CODE - //---------------------------------------------------------------------- - { - uint32_t l_data; - TARGETING::TargetHandleList l_dimmList; - getAllLogicalCards( l_dimmList, TARGETING::TYPE_DIMM ); - - for( size_t i = 0; i < l_dimmList.size(); i++) - { - fapi::Target l_target( fapi::TARGET_TYPE_DIMM, - (void *)(l_dimmList[i]) ); - l_rc = FAPI_ATTR_GET(ATTR_POS, &l_target, l_data); - - if (l_rc) - { - FAPI_ERR("hwpTestAttributes: ATTR_POS. Error from GET"); - break; - } - else - { - FAPI_INF("hwpTestAttributes: ATTR_POS = %d", l_data); - } - } - - if (l_rc) - { - break; - } - } - - //---------------------------------------------------------------------- - // Test ATTR_MSS_DIMM_MFG_ID_CODE - //---------------------------------------------------------------------- - { - uint32_t l_data[2][2]; - - TARGETING::PredicateCTM l_pred(TARGETING::CLASS_UNIT, TARGETING::TYPE_MBA); - TARGETING::TargetRangeFilter l_filter(TARGETING::targetService().begin(), - TARGETING::targetService().end(), - &l_pred); - - // Just look at the first MBA chiplet - if (l_filter) - { - fapi::Target l_target(fapi::TARGET_TYPE_MBA_CHIPLET, *l_filter); - - l_rc = FAPI_ATTR_GET(ATTR_MSS_DIMM_MFG_ID_CODE, &l_target, l_data); - - if (l_rc) - { - FAPI_ERR("hwpTestAttributes: ATTR_MSS_DIMM_MFG_ID_CODE. Error from GET"); - break; - } - } - else - { - FAPI_ERR("hwpTestAttributes: ATTR_MSS_DIMM_MFG_ID_CODE. No MBAs found"); - FAPI_SET_HWP_ERROR(l_rc, RC_HWP_ATTR_UNIT_TEST_FAIL); - break; - } - } - - //---------------------------------------------------------------------- // Test ATTR_SCRATCH_UINT8_1 //---------------------------------------------------------------------- { @@ -940,260 +876,312 @@ fapi::ReturnCode hwpTestAttributes() } //---------------------------------------------------------------------- - // Test non-const Attribute Override on ATTR_SCRATCH_UINT64_1 + // Test AttributeTank functions with empty tank //---------------------------------------------------------------------- { - if (fapi::platAttrSvc::overridesExistWrap()) + // Create a local OverrideAttributeTank (this is not the singleton) + fapi::OverrideAttributeTank l_tank; + + // Check that tank is empty + if (l_tank.attributesExist()) { - FAPI_INF("hwpTestAttributes: OverrideUint64. Overrides exist, skipping test"); + FAPI_SET_HWP_ERROR(l_rc, RC_HWP_ATTR_UNIT_TEST_FAIL); + FAPI_ERR("hwpTestAttributes: Error. AttributeTank is not empty (1.1)"); + break; } - else + + // 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)) { - // Set the attribute to a known value - uint64_t l_val = 4; - l_rc = FAPI_ATTR_SET(ATTR_SCRATCH_UINT64_1, NULL, l_val); - - if (l_rc) - { - FAPI_ERR("hwpTestAttributes: OverrideUint64. Error from SET"); - break; - } - - // Create an non-const override - fapi::AttributeOverride l_override; - l_override.iv_overrideVal = 9; - l_override.iv_attrId = - static_cast<uint32_t>(fapi::ATTR_SCRATCH_UINT64_1); - l_override.iv_targetType = - static_cast<uint32_t>(fapi::TARGET_TYPE_SYSTEM); - l_override.iv_pos = fapi::ATTR_POS_NA; - l_override.iv_unitPos = fapi::ATTR_UNIT_POS_NA; - l_override.iv_overrideType = fapi::ATTR_OVERRIDE_NON_CONST; - l_override.iv_arrayD1 = fapi::ATTR_ARRAYD_NA; - l_override.iv_arrayD2 = fapi::ATTR_ARRAYD_NA; - l_override.iv_arrayD3 = fapi::ATTR_ARRAYD_NA; - l_override.iv_arrayD4 = fapi::ATTR_ARRAYD_NA; - fapi::platAttrSvc::setOverrideWrap(l_override); - - // Check that the override value is returned - l_rc = FAPI_ATTR_GET(ATTR_SCRATCH_UINT64_1, NULL, l_val); - - if (l_rc) - { - FAPI_ERR("hwpTestAttributes: OverrideUint64. Error from GET"); - break; - } - - if (l_val != 9) - { - FAPI_SET_HWP_ERROR(l_rc, RC_HWP_ATTR_UNIT_TEST_FAIL); - FAPI_ERR("hwpTestAttributes: OverrideUint64 GET returned %d", - static_cast<uint32_t>(l_val)); - break; - } - - // Set the attribute to a known value - l_val = 8; - l_rc = FAPI_ATTR_SET(ATTR_SCRATCH_UINT64_1, NULL, l_val); - - if (l_rc) - { - FAPI_ERR("hwpTestAttributes: OverrideUint64. Error from SET (2)"); - break; - } - - // Check that the override was cancelled (it is a non-const override) - l_val = 0; - l_rc = FAPI_ATTR_GET(ATTR_SCRATCH_UINT64_1, NULL, l_val); - - if (l_rc) - { - FAPI_ERR("hwpTestAttributes: OverrideUint64. Error from GET (2)"); - break; - } - - if (l_val != 8) - { - FAPI_SET_HWP_ERROR(l_rc, RC_HWP_ATTR_UNIT_TEST_FAIL); - FAPI_ERR("hwpTestAttributes: OverrideUint64 GET returned %d (2)", - static_cast<uint32_t>(l_val)); - break; - } - - // Clear all overrides - fapi::platAttrSvc::clearOverridesWrap(); + 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 const Attribute Override on ATTR_SCRATCH_UINT8_1 + // Test AttributeTank functions with single attribute in tank //---------------------------------------------------------------------- { - if (fapi::platAttrSvc::overridesExistWrap()) + // 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_INF("hwpTestAttributes: OverrideUint8. Overrides exist, skipping test"); + FAPI_SET_HWP_ERROR(l_rc, RC_HWP_ATTR_UNIT_TEST_FAIL); + FAPI_ERR("hwpTestAttributes: Error. AttributeTank is empty (2.1)"); + break; } - else + + // Try to get the wrong attribute from the tank + l_val = 0; + if (l_tank.getAttribute(fapi::ATTR_SCRATCH_UINT64_2, NULL, l_val)) { - // Set the attribute to a known value - uint8_t l_val = 1; - l_rc = FAPI_ATTR_SET(ATTR_SCRATCH_UINT8_1, NULL, l_val); - - if (l_rc) - { - FAPI_ERR("hwpTestAttributes: OverrideUint8. Error from SET"); - break; - } - - // Create a const override - fapi::AttributeOverride l_override; - l_override.iv_overrideVal = 2; - l_override.iv_attrId = - static_cast<uint32_t>(fapi::ATTR_SCRATCH_UINT8_1); - l_override.iv_targetType = - static_cast<uint32_t>(fapi::TARGET_TYPE_SYSTEM); - l_override.iv_pos = fapi::ATTR_POS_NA; - l_override.iv_unitPos = fapi::ATTR_UNIT_POS_NA; - l_override.iv_overrideType = fapi::ATTR_OVERRIDE_CONST; - l_override.iv_arrayD1 = fapi::ATTR_ARRAYD_NA; - l_override.iv_arrayD2 = fapi::ATTR_ARRAYD_NA; - l_override.iv_arrayD3 = fapi::ATTR_ARRAYD_NA; - l_override.iv_arrayD4 = fapi::ATTR_ARRAYD_NA; - fapi::platAttrSvc::setOverrideWrap(l_override); - - // Check that the override value is returned - l_rc = FAPI_ATTR_GET(ATTR_SCRATCH_UINT8_1, NULL, l_val); - - if (l_rc) - { - FAPI_ERR("hwpTestAttributes: OverrideUint8. Error from GET"); - break; - } - - if (l_val != 2) - { - FAPI_SET_HWP_ERROR(l_rc, RC_HWP_ATTR_UNIT_TEST_FAIL); - FAPI_ERR("hwpTestAttributes: OverrideUint8 GET returned %d", - l_val); - break; - } - - // Set the attribute to a known value - l_val = 3; - l_rc = FAPI_ATTR_SET(ATTR_SCRATCH_UINT8_1, NULL, l_val); - - if (l_rc) - { - FAPI_ERR("hwpTestAttributes: OverrideUint8. Error from SET (2)"); - break; - } - - // Check that the override value is still returned - l_val = 0; - l_rc = FAPI_ATTR_GET(ATTR_SCRATCH_UINT8_1, NULL, l_val); - - if (l_rc) - { - FAPI_ERR("hwpTestAttributes: OverrideUint8. Error from GET (2)"); - break; - } - - if (l_val != 2) - { - FAPI_SET_HWP_ERROR(l_rc, RC_HWP_ATTR_UNIT_TEST_FAIL); - FAPI_ERR("hwpTestAttributes: OverrideUint8 GET returned %d (2)", - l_val); - break; - } - - // Clear all overrides - fapi::platAttrSvc::clearOverridesWrap(); - - // Check that the real value is now returned - l_val = 0; - l_rc = FAPI_ATTR_GET(ATTR_SCRATCH_UINT8_1, NULL, l_val); - - if (l_rc) - { - FAPI_ERR("hwpTestAttributes: OverrideUint8. Error from GET (3)"); - break; - } - - if (l_val != 3) - { - FAPI_SET_HWP_ERROR(l_rc, RC_HWP_ATTR_UNIT_TEST_FAIL); - FAPI_ERR("hwpTestAttributes: OverrideUint8 GET returned %d (3)", - l_val); - break; - } + 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%llx) from tank (2.7)", + l_pAttr[0].iv_val); + break; + } + delete [] l_attributes[0].iv_pAttributes; + } //---------------------------------------------------------------------- - // Test non-const Attribute Override on ATTR_SCRATCH_UINT64_ARRAY_2 + // Test AttributeTank functions with multiple attributes in tank //---------------------------------------------------------------------- { - if (fapi::platAttrSvc::overridesExistWrap()) + // 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_INF("hwpTestAttributes: OverrideUint64array. Overrides exist, skipping test"); + 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; } - else + + if (l_val != 4) { - // Create a non-const override - fapi::AttributeOverride l_override; - l_override.iv_attrId = - static_cast<uint32_t>(fapi::ATTR_SCRATCH_UINT64_ARRAY_2); - l_override.iv_targetType = - static_cast<uint32_t>(fapi::TARGET_TYPE_SYSTEM); - l_override.iv_pos = fapi::ATTR_POS_NA; - l_override.iv_unitPos = fapi::ATTR_UNIT_POS_NA; - l_override.iv_overrideType = fapi::ATTR_OVERRIDE_NON_CONST; - l_override.iv_arrayD3 = fapi::ATTR_ARRAYD_NA; - l_override.iv_arrayD4 = fapi::ATTR_ARRAYD_NA; - - l_override.iv_overrideVal = 20; - l_override.iv_arrayD1 = 0; - l_override.iv_arrayD2 = 0; - fapi::platAttrSvc::setOverrideWrap(l_override); - - l_override.iv_overrideVal = 21; - l_override.iv_arrayD1 = 0; - l_override.iv_arrayD2 = 1; - fapi::platAttrSvc::setOverrideWrap(l_override); - - l_override.iv_overrideVal = 22; - l_override.iv_arrayD1 = 1; - l_override.iv_arrayD2 = 0; - fapi::platAttrSvc::setOverrideWrap(l_override); - - l_override.iv_overrideVal = 0xfffffffe; - l_override.iv_arrayD1 = 1; - l_override.iv_arrayD2 = 1; - fapi::platAttrSvc::setOverrideWrap(l_override); - - // Check that the override value is returned - uint64_t l_val[2][2]; - l_rc = FAPI_ATTR_GET(ATTR_SCRATCH_UINT64_ARRAY_2, NULL, l_val); - - if (l_rc) - { - FAPI_ERR("hwpTestAttributes: OverrideUint64array. Error from GET"); - break; - } - - if ((l_val[0][0] != 20) || (l_val[0][1] != 21) || - (l_val[1][0] != 22) || (l_val[1][1] != 0xfffffffe)) - { - FAPI_SET_HWP_ERROR(l_rc, RC_HWP_ATTR_UNIT_TEST_FAIL); - FAPI_ERR("hwpTestAttributes: OverrideUint64array GET returned 0x%llx:0x%llx:0x%llx:0x%llx", - l_val[0][0], l_val[0][1], l_val[1][0], l_val[1][1]); - break; - } + FAPI_SET_HWP_ERROR(l_rc, RC_HWP_ATTR_UNIT_TEST_FAIL); + FAPI_ERR("hwpTestAttributes: Error. Got bad value (0x%llx) 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); + } + + //---------------------------------------------------------------------- + // 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); - // Clear all overrides - fapi::platAttrSvc::clearOverridesWrap(); + // 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); } } while (0); diff --git a/src/usr/hwpf/plat/fapiPlatAttrOverrideDirect.C b/src/usr/hwpf/plat/fapiPlatAttrOverrideDirect.C deleted file mode 100644 index 436a63477..000000000 --- a/src/usr/hwpf/plat/fapiPlatAttrOverrideDirect.C +++ /dev/null @@ -1,56 +0,0 @@ -/* IBM_PROLOG_BEGIN_TAG - * This is an automatically generated prolog. - * - * $Source: src/usr/hwpf/plat/fapiPlatAttrOverrideDirect.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 - */ -/** - * @file fapiPlatAttrOverrideDirect.C - * - * @brief Defines a PLAT function that applies a HWPF Attribute Override - * written directly into Hostboot memory from the Simics/VBU console - */ - -//****************************************************************************** -// Includes -//****************************************************************************** -#include <util/singleton.H> -#include <hwpf/fapi/fapiAttributeOverride.H> - -namespace fapi -{ - -//****************************************************************************** -// Global Variables -//****************************************************************************** -AttributeOverride g_attrOverride; - -//****************************************************************************** -// platAttrOverrideDirect -// Apply a HWPF Attribute Override written directly into Hostboot memory from -// the Simics/VBU console. This function is called by a Simics/VBU debug tool -//****************************************************************************** -void platAttrOverrideDirect() -{ - // Apply the attribute override - Singleton<fapi::AttributeOverrides>::instance().setOverride(g_attrOverride); -} - -} diff --git a/src/usr/hwpf/plat/fapiPlatAttrOverrideSync.C b/src/usr/hwpf/plat/fapiPlatAttrOverrideSync.C new file mode 100644 index 000000000..4217ad828 --- /dev/null +++ b/src/usr/hwpf/plat/fapiPlatAttrOverrideSync.C @@ -0,0 +1,371 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/usr/hwpf/plat/fapiPlatAttrOverrideSync.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 fapiPlatAttrOverrideSync.C + * + * @brief Implements the functions for Attribute Override and Sync + * + */ + +//****************************************************************************** +// Includes +//****************************************************************************** +#include <limits.h> +#include <sys/msg.h> +#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> + +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 +}; + +//****************************************************************************** +// Apply a HWPF Attribute Override written directly into Hostboot memory from +// the Simics/VBU console. This function is called by a Simics/VBU debug tool +//****************************************************************************** +void directOverride() +{ + // Apply the attribute override + Singleton<fapi::OverrideAttributeTank>::instance(). + setAttribute(g_attrOverride); +} + +//****************************************************************************** +void 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 + // error and then wait forever for a message to appear on the queue + 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). + FAPI_INF("monitorForFspMessages: MSG_SET_OVERRIDES"); + uint64_t l_size = l_pMsg->data[1]; + Attribute * l_pAttribute = + reinterpret_cast<Attribute *>(l_pMsg->extra_data); + + while (l_size > sizeof(fapi::Attribute)) + { + Singleton<fapi::OverrideAttributeTank>::instance(). + setAttribute(*l_pAttribute); + l_pAttribute++; + l_size -= sizeof(fapi::Attribute); + } + + // Free the memory + free(l_pMsg->extra_data); + l_pMsg->extra_data = NULL; + l_pMsg->data[1] = 0; + + if (msg_is_async(l_pMsg)) + { + msg_free(l_pMsg); + } + else + { + // Send the message back as a response + msg_respond(l_pMsgQ, l_pMsg); + } + } + else if (l_pMsg->type == MSG_CLEAR_ALL_OVERRIDES) + { + // FSP is clearing all attribute overrides. + FAPI_INF("monitorForFspMessages: MSG_CLEAR_ALL_OVERRIDES"); + Singleton<fapi::OverrideAttributeTank>::instance(). + clearAllAttributes(); + + // Send message back as response + msg_respond(l_pMsgQ, l_pMsg); + } + else + { + FAPI_ERR("monitorForFspMessages: Unrecognized message 0x%x", + l_pMsg->type); + } + } +} + +//****************************************************************************** +// Utility function called by sendAttrOverridesAndSyncsToFsp +//****************************************************************************** +errlHndl_t sendAttrsToFsp(const MAILBOX_MSG_TYPE i_msgType, + std::vector<AttributeChunk> & i_attributes) +{ + errlHndl_t l_pErr = NULL; + + // Send Attributes through the mailbox chunk by chunk. + for (size_t i = 0; i < i_attributes.size(); i++) + { + 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; + + // 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); + break; + } + + // Mailbox freed the chunk data + i_attributes[i].iv_pAttributes = NULL; + msg_free(l_pMsg); + } + + // 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++) + { + free(i_attributes[i].iv_pAttributes); + i_attributes[i].iv_pAttributes = NULL; + } + i_attributes.clear(); + + return l_pErr; +} + +//****************************************************************************** +void sendAttrOverridesAndSyncsToFsp() +{ + if (MBOX::mailbox_enabled()) + { + // Clear all current FSP Attribute Overrides + msg_t * l_pMsg = msg_allocate(); + l_pMsg->type = MSG_CLEAR_ALL_OVERRIDES; + l_pMsg->data[0] = 0; + l_pMsg->data[1] = 0; + l_pMsg->extra_data = NULL; + + // 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 + errlHndl_t l_pErr = MBOX::sendrecv(MBOX::FSP_HWPF_ATTR_MSGQ, l_pMsg); + msg_free(l_pMsg); + + if (l_pErr) + { + FAPI_ERR("SendAttrOverridesToFsp: Error clearing FSP overrides"); + errlCommit(l_pErr, HWPF_COMP_ID); + } + else + { + // 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()) + { + l_pErr = sendAttrsToFsp(MSG_SET_OVERRIDES, l_attributes); + + if (l_pErr) + { + FAPI_ERR("SendAttrOverridesToFsp: Error sending overrides to FSP"); + errlCommit(l_pErr, HWPF_COMP_ID); + } + } + + if (l_pErr == NULL) + { + // Send Hostboot Attributes to Sync to the FSP + std::vector<AttributeChunk> l_attributes; + + Singleton<fapi::SyncAttributeTank>::instance(). + getAllAttributes(AttributeTank::ALLOC_TYPE_MALLOC, + l_attributes); + + if (l_attributes.size()) + { + l_pErr = sendAttrsToFsp(MSG_SET_SYNC_ATTS, l_attributes); + + if (l_pErr) + { + FAPI_ERR("SendAttrOverridesToFsp: Error sending syncs to FSP"); + errlCommit(l_pErr, HWPF_COMP_ID); + } + else + { + // Clear Hostboot Attributes to Sync + Singleton<fapi::SyncAttributeTank>::instance(). + clearAllAttributes(); + } + } + } + } + } +} + +//****************************************************************************** +AttributeTank & theOverrideAttrTank() +{ + return Singleton<fapi::OverrideAttributeTank>::instance(); +} + +//****************************************************************************** +AttributeTank & theSyncAttrTank() +{ + return Singleton<fapi::SyncAttributeTank>::instance(); +} + +//****************************************************************************** +// This is used as a singleton and contains the lock used to serialize access +// to the OverrideAttributeTank +//****************************************************************************** +class OverrideAttributeTankLock +{ +public: + OverrideAttributeTankLock() + { + mutex_init(&iv_mutex); + } + + ~OverrideAttributeTankLock() + { + mutex_destroy(&iv_mutex); + } + mutex_t iv_mutex; +}; + +//****************************************************************************** +// This is used as a singleton and contains the lock used to serialize access +// to the SyncAttributeTank +//****************************************************************************** +class SyncAttributeTankLock +{ +public: + SyncAttributeTankLock() + { + mutex_init(&iv_mutex); + } + + ~SyncAttributeTankLock() + { + mutex_destroy(&iv_mutex); + } + mutex_t iv_mutex; +}; + +} // End attrOverrideSync namespace + +//****************************************************************************** +// This is the Hostboot PLAT implementation of a FAPI function +//****************************************************************************** +void OverrideAttributeTank::platLock() const +{ + mutex_lock(&(Singleton<fapi::attrOverrideSync:: + OverrideAttributeTankLock>::instance().iv_mutex)); +} + +//****************************************************************************** +// This is the Hostboot PLAT implementation of a FAPI function +//****************************************************************************** +void OverrideAttributeTank::platUnlock() const +{ + mutex_unlock(&(Singleton<fapi::attrOverrideSync:: + OverrideAttributeTankLock>::instance().iv_mutex)); +} + +//****************************************************************************** +// This is the Hostboot PLAT implementation of a FAPI function +//****************************************************************************** +void SyncAttributeTank::platLock() const +{ + mutex_lock(&(Singleton<fapi::attrOverrideSync:: + SyncAttributeTankLock>::instance().iv_mutex)); +} + +//****************************************************************************** +// This is the Hostboot PLAT implementation of a FAPI function +//****************************************************************************** +void SyncAttributeTank::platUnlock() const +{ + mutex_unlock(&(Singleton<fapi::attrOverrideSync:: + SyncAttributeTankLock>::instance().iv_mutex)); +} + +//****************************************************************************** +// This is the Hostboot PLAT implementation of a FAPI function +//****************************************************************************** +bool SyncAttributeTank::platSyncEnabled() +{ + // 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; +} + +} // End fapi namespace diff --git a/src/usr/hwpf/plat/fapiPlatAttributeService.C b/src/usr/hwpf/plat/fapiPlatAttributeService.C index a1778861d..d24d3665f 100644 --- a/src/usr/hwpf/plat/fapiPlatAttributeService.C +++ b/src/usr/hwpf/plat/fapiPlatAttributeService.C @@ -23,7 +23,7 @@ /** * @file fapiPlatAttributeService.C * - * @brief Implements HWP attribute -> HB attribute bridging functions + * @brief Implements the functions that access attributes * */ @@ -706,75 +706,6 @@ fapi::ReturnCode fapiPlatGetTargetPos(const fapi::Target * i_pFapiTarget, return l_rc; } -//****************************************************************************** -// fapi::platAttrSvc::getOverrideWrap function -//****************************************************************************** -bool getOverrideWrap(const fapi::AttributeId i_attrId, - const fapi::Target * const i_pTarget, - uint64_t & o_overrideVal, - const uint8_t i_arrayD1, - const uint8_t i_arrayD2, - const uint8_t i_arrayD3, - const uint8_t i_arrayD4) -{ - return Singleton<fapi::AttributeOverrides>::instance().getOverride( - i_attrId, i_pTarget, o_overrideVal, i_arrayD1, i_arrayD2, i_arrayD3, - i_arrayD4); -} - -//****************************************************************************** -// fapi::platAttrSvc::clearNonConstOverrideWrap function -//****************************************************************************** -void clearNonConstOverrideWrap(const fapi::AttributeId i_attrId, - const fapi::Target * const i_pTarget) -{ - Singleton<fapi::AttributeOverrides>::instance().clearNonConstOverride( - i_attrId, i_pTarget); -} - -//****************************************************************************** -// fapi::platAttrSvc::setOverrideWrap function -//****************************************************************************** -void setOverrideWrap(const AttributeOverride & i_override) -{ - Singleton<fapi::AttributeOverrides>::instance().setOverride(i_override); -} - -//****************************************************************************** -// fapi::platAttrSvc::clearOverridesWrap function -//****************************************************************************** -void clearOverridesWrap() -{ - Singleton<fapi::AttributeOverrides>::instance().clearOverrides(); -} - -//****************************************************************************** -// fapi::platAttrSvc::overridesExistWrap function -//****************************************************************************** -bool overridesExistWrap() -{ - return Singleton<fapi::AttributeOverrides>::instance().overridesExist(); -} - -//****************************************************************************** -// fapi::platAttrSvc::AttributeOverridesLock class -// This is a simple container for a mutex -//****************************************************************************** -class AttributeOverridesLock -{ -public: - AttributeOverridesLock() - { - mutex_init(&iv_mutex); - } - - ~AttributeOverridesLock() - { - mutex_destroy(&iv_mutex); - } - mutex_t iv_mutex; -}; - /** * @enum * Return values for ATTR_PROC_*_BAR_ENABLE @@ -1494,24 +1425,4 @@ fapi::ReturnCode fapiPlatGetProcPcieBarSize ( } // End platAttrSvc namespace -//****************************************************************************** -// fapi::AttributeOverrides::platLock function -// This is the Hostboot PLAT implementation of the FAPI function -//****************************************************************************** -void AttributeOverrides::platLock() -{ - mutex_lock(&(Singleton - <fapi::platAttrSvc::AttributeOverridesLock>::instance().iv_mutex)); -} - -//****************************************************************************** -// fapi::AttributeOverrides::platUnlock function -// This is the Hostboot PLAT implementation of the FAPI function -//****************************************************************************** -void AttributeOverrides::platUnlock() -{ - mutex_unlock(&(Singleton - <fapi::platAttrSvc::AttributeOverridesLock>::instance().iv_mutex)); -} - } // End fapi namespace diff --git a/src/usr/hwpf/plat/fapiPlatTask.C b/src/usr/hwpf/plat/fapiPlatTask.C index c5cade74b..4232f7aae 100644 --- a/src/usr/hwpf/plat/fapiPlatTask.C +++ b/src/usr/hwpf/plat/fapiPlatTask.C @@ -30,10 +30,10 @@ //****************************************************************************** // Includes //****************************************************************************** -#include <sys/task.h> #include <initservice/taskargs.H> -#include <hwpf/fapi/fapiAttributeOverride.H> -#include <fapiPlatTrace.H> +#include <hwpf/fapi/fapiAttributeTank.H> +#include <hwpf/plat/fapiPlatAttrOverrideSync.H> +#include <hwpf/plat/fapiPlatTrace.H> namespace fapi { @@ -41,23 +41,40 @@ namespace fapi //****************************************************************************** // Global Variables //****************************************************************************** -// Defined in fapiPlatAttrOverrideDirect.C -extern AttributeOverride g_attrOverride; +// Defined in fapiPlatAttrOverrideSync.C +extern Attribute g_attrOverride; //****************************************************************************** -// platTaskEntry -// This function writes the g_attrOverride global variable first written by the -// Simics/VBU console and then read by fapiPlatAttrOverrideDirect.C to ensure -// it is paged and pinned in memory +// This function monitors for FSP mailbox messages +//****************************************************************************** +void * platMonitorForFspMessages(void * i_pContext) +{ + FAPI_IMP("Starting platMonitorForFspMessages"); + fapi::attrOverrideSync::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 starts a task that monitors for FSP mailbox messages on the +// HB_HWPF_ATTR_MSGQ message queue //****************************************************************************** void platTaskEntry(errlHndl_t &io_errl) { FAPI_IMP("Starting platTaskEntry"); - g_attrOverride.iv_overrideVal = 0; - io_errl=NULL; + + // Write the g_attrOverride global + g_attrOverride.iv_val = 0; + + // Start task that monitors for FSP mailbox messages + task_create(fapi::platMonitorForFspMessages, NULL); } +} // End fapi namespace + // Macro that creates the _start function TASK_ENTRY_MACRO(fapi::platTaskEntry); - -} // End fapi namespace diff --git a/src/usr/hwpf/plat/makefile b/src/usr/hwpf/plat/makefile index 4bb17e545..11a7a8c11 100644 --- a/src/usr/hwpf/plat/makefile +++ b/src/usr/hwpf/plat/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/hwpf/plat/makefile $ +# $Source: src/usr/hwpf/plat/makefile $ # -# IBM CONFIDENTIAL +# IBM CONFIDENTIAL # -# COPYRIGHT International Business Machines Corp. 2011-2012 +# COPYRIGHT International Business Machines Corp. 2011,2012 # -# 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 ROOTPATH = ../../../.. MODULE = plat @@ -37,6 +37,6 @@ OBJS = fapiPlatHwAccess.o \ fapiPlatAttributeService.o \ fapiPlatMvpdAccess.o \ fapiPlatTask.o \ - fapiPlatAttrOverrideDirect.o + fapiPlatAttrOverrideSync.o include ${ROOTPATH}/config.mk diff --git a/src/usr/hwpf/test/hwpftest.H b/src/usr/hwpf/test/hwpftest.H index 07d00044d..2f8ce4195 100644 --- a/src/usr/hwpf/test/hwpftest.H +++ b/src/usr/hwpf/test/hwpftest.H @@ -252,13 +252,53 @@ public: /** * @brief Test HWPF Attributes: call a test procedure that exercises - * the FAPI scratch attributes + * FAPI attributes */ void testHwpf4() { errlHndl_t l_err = NULL; - FAPI_INVOKE_HWP(l_err, hwpTestAttributes); + // 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) { diff --git a/src/usr/initservice/istepdispatcher/istepdispatcher.C b/src/usr/initservice/istepdispatcher/istepdispatcher.C index 4ab29b806..f52cc1db7 100644 --- a/src/usr/initservice/istepdispatcher/istepdispatcher.C +++ b/src/usr/initservice/istepdispatcher/istepdispatcher.C @@ -53,6 +53,8 @@ #include <targeting/common/attributes.H> // ISTEP_MODE attribute #include <targeting/common/targetservice.H> +#include <hwpf/plat/fapiPlatAttributeService.H> + #include <mbox/mbox_queues.H> // HB_ISTEP_MSGQ #include <mbox/mboxif.H> // register mailbox @@ -752,6 +754,11 @@ void IStepDispatcher::handleMoreWorkNeededMsg ( bool i_first ) iv_Msg->data[0], iv_Msg->data[1], iv_Msg->extra_data ); + + // Send the potentially modified set of HWPF Attribute overrides and any + // HWPF Attributes to sync to the FSP + fapi::attrOverrideSync::sendAttrOverridesAndSyncsToFsp(); + msg_respond( iv_msgQ, iv_Msg ); iv_Msg = NULL; diff --git a/src/usr/initservice/istepdispatcher/makefile b/src/usr/initservice/istepdispatcher/makefile index 04a6da054..041d27794 100644 --- a/src/usr/initservice/istepdispatcher/makefile +++ b/src/usr/initservice/istepdispatcher/makefile @@ -1,28 +1,33 @@ -# IBM_PROLOG_BEGIN_TAG -# This is an automatically generated prolog. +# IBM_PROLOG_BEGIN_TAG +# This is an automatically generated prolog. # -# $Source: src/usr/initservice/istepdispatcher/makefile $ +# $Source: src/usr/initservice/istepdispatcher/makefile $ # -# IBM CONFIDENTIAL +# IBM CONFIDENTIAL # -# COPYRIGHT International Business Machines Corp. 2011-2012 +# COPYRIGHT International Business Machines Corp. 2011,2012 # -# 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 ROOTPATH = ../../../.. MODULE = istepdisp +EXTRAINCDIR += ${ROOTPATH}/src/include/usr/ecmddatabuffer +EXTRAINCDIR += ${ROOTPATH}/src/include/usr/hwpf/fapi +EXTRAINCDIR += ${ROOTPATH}/src/include/usr/hwpf/plat +EXTRAINCDIR += ${ROOTPATH}/src/include/usr/hwpf/hwp + OBJS = istepdispatcher.o initsvcudistep.o \ sptask.o splesscommon.o istepWorker.o |