diff options
| author | Luis Fernandez <Luis.Fernandez@ibm.com> | 2019-04-22 14:27:12 -0500 |
|---|---|---|
| committer | Daniel M. Crowell <dcrowell@us.ibm.com> | 2019-05-09 16:32:36 -0500 |
| commit | fe000f81b6492f77e783f72b408260d5346b9757 (patch) | |
| tree | 553a97646b7152ef4b09810aad855277903287eb /src | |
| parent | d2da0774fa01e5bb89a717baf814e43f5f3fef0a (diff) | |
| download | blackbird-hostboot-fe000f81b6492f77e783f72b408260d5346b9757.tar.gz blackbird-hostboot-fe000f81b6492f77e783f72b408260d5346b9757.zip | |
Revisit attributes with array types.
Use std::array to set and get attributes' value that support array.
Change-Id: I9dc31bbca5ad0c56add353c6d4233296d2bb200a
RTC: 110583
Reviewed-on: http://rchgit01.rchland.ibm.com/gerrit1/76347
Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com>
Reviewed-by: Ilya Smirnov <ismirno@us.ibm.com>
Tested-by: Jenkins OP Build CI <op-jenkins+hostboot@us.ibm.com>
Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com>
Reviewed-by: Nicholas E. Bofferding <bofferdn@us.ibm.com>
Tested-by: Jenkins OP HW <op-hw-jenkins+hostboot@us.ibm.com>
Reviewed-by: Daniel M. Crowell <dcrowell@us.ibm.com>
Diffstat (limited to 'src')
| -rw-r--r-- | src/include/usr/targeting/common/target.H | 152 | ||||
| -rw-r--r-- | src/usr/targeting/common/target.C | 12 | ||||
| -rwxr-xr-x | src/usr/targeting/common/xmltohb/xmltohb.pl | 90 | ||||
| -rw-r--r-- | src/usr/targeting/test/testtargeting.H | 123 |
4 files changed, 348 insertions, 29 deletions
diff --git a/src/include/usr/targeting/common/target.H b/src/include/usr/targeting/common/target.H index 08fcb3f76..bfb5e70c7 100644 --- a/src/include/usr/targeting/common/target.H +++ b/src/include/usr/targeting/common/target.H @@ -47,6 +47,9 @@ #include <targeting/common/util.H> #include <targeting/common/pointer.H> #include <vector> +#ifdef __HOSTBOOT_MODULE +#include <array> +#endif // This component #include <targeting/common/attributes.H> @@ -181,6 +184,34 @@ class Target template<const ATTRIBUTE_ID A> bool tryGetAttrNotSynced( typename AttributeTraits<A>::Type& o_attrValue) const; + + /** + * @brief Try to get the target's specified std::array attribute value + * + * A special tryGetAttr function for getting the attribute values + * of the attributes which support std::array. + * It returns false (with invalid o_attrValue) if the specified + * attribute does not exist for the associated target, true (with a + * valid o_attrValue) otherwise. + * + * @param[out] o_attrValue Value of the attribute + * + * @pre Target service must be initialized + * + * @post See "return" + * + * @return bool indicating whether the specified attribute was returned + * or not + * + * @retval true Attribute returned in o_attrValue + * @retval false Attribute not found; o_attValue not valid + */ +#ifdef __HOSTBOOT_MODULE + template<const ATTRIBUTE_ID A> + bool tryGetAttr( + typename AttributeTraits<A>::TypeStdArr& o_attrValue) const; +#endif + /** * @brief Get the target's specified attribute value * @@ -250,6 +281,26 @@ class Target const char* getAttrAsString() const; /** + * @brief For targets whose attribute value type is an array, return + * the array in std::array form. + * + * @pre Target service must be initialized + * + * @post Target's specified attribute value returned as a std::array, + * or assert called if specified attribute doesn't exist for the + * associated target or type is not an array + * + * @return std::array + * + * @retval Content and dimension varies, see xml file where the + * attribute's type is set + */ +#ifdef __HOSTBOOT_MODULE + template<const ATTRIBUTE_ID A> + typename AttributeTraits<A>::TypeStdArr getAttrAsStdArr() const; +#endif + + /** * @brief Tries to set the target's specified attribute value * * Attempts to set the target's specified attribute value. It @@ -298,6 +349,34 @@ class Target typename AttributeTraits<A>::Type const& i_attrValue); /** + * + * @brief Tries to set the target's specified std::array attribute value + * + * A special trySetAttr function for setting the attribute values + * of the attributes which support std::array. + * It returns false if the specified attribute does not exist for the + * associated target, true otherwise. + * + * @param[in] i_attrValue Value of the attribute + * + * @pre Target service must be initialized + * + * @post Target's attribute value updated (if it exists), and caller + * notified whether the update occurred or not. + * + * @return bool indicating whether the specified attribute was updated + * or not + * + * @retval true Attribute updated + * @retval false Attribute not updated + */ +#ifdef __HOSTBOOT_MODULE + template<const ATTRIBUTE_ID A> + bool trySetAttr( + typename AttributeTraits<A>::TypeStdArr const& i_attrValue); +#endif + + /** * @brief Returns pointer to a mutex attribute associated with the * target * @@ -361,6 +440,23 @@ class Target void setAttr(typename AttributeTraits<A>::Type const& i_attrValue); /** + * @brief For targets whose attribute value type is an array, set value + * from a std::array of any dimension + * + * @param[in] i_attrValue Value of the attribute + * + * @pre Target service must be initialized + * + * @post Target's attribute value updated if it exists and if it + * suppports TypeStdArr type, otherwise routine asserts + */ +#ifdef __HOSTBOOT_MODULE + template<const ATTRIBUTE_ID A> + void setAttrFromStdArr(typename AttributeTraits<A>::TypeStdArr const& + i_attrValue); +#endif + + /** * @brief Perform FFDC for the target instance * * @param[out] io_size @@ -729,8 +825,10 @@ class Target enum TargAssertReason { SET_ATTR, + SET_ATTR_FROM_STD_ARR, GET_ATTR, GET_ATTR_AS_STRING, + GET_ATTR_AS_STD_ARRAY, GET_HB_MUTEX_ATTR, GET_ATTR_TANK_TARGET_POS_DATA, GET_ATTR_TANK_TARGET_POS_DATA_ATTR, @@ -865,6 +963,19 @@ bool Target::tryGetAttr(typename AttributeTraits<A>::Type& o_attrValue) const return _tryGetAttr(A,sizeof(o_attrValue),&o_attrValue); } +#ifdef __HOSTBOOT_MODULE +template<const ATTRIBUTE_ID A> +bool Target::tryGetAttr( + typename AttributeTraits<A>::TypeStdArr& o_attrValue) const +{ + if(AttributeTraits<A>::readable == AttributeTraits<A>::readable) { } + if(AttributeTraits<A>::notHbMutex == AttributeTraits<A>::notHbMutex) { } + if(AttributeTraits<A>::fspAccessible == AttributeTraits<A>::fspAccessible) + { } + return _tryGetAttr(A, sizeof(o_attrValue), &o_attrValue); +} +#endif + template<const ATTRIBUTE_ID A> bool Target::trySetAttr(typename AttributeTraits<A>::Type const& i_attrValue) { @@ -886,6 +997,17 @@ bool Target::trySetAttrNotSynced( return _trySetAttr(A,sizeof(i_attrValue),&i_attrValue); } +#ifdef __HOSTBOOT_MODULE +template<const ATTRIBUTE_ID A> +bool Target::trySetAttr(typename AttributeTraits<A>::TypeStdArr + const& i_attrValue) +{ + if(AttributeTraits<A>::writeable == AttributeTraits<A>::writeable) { } + if(AttributeTraits<A>::notHbMutex == AttributeTraits<A>::notHbMutex) { } + return _trySetAttr(A,sizeof(i_attrValue),&i_attrValue); +} +#endif + template<const ATTRIBUTE_ID A> typename AttributeTraits<A>::Type Target::getAttr() const { @@ -933,6 +1055,19 @@ void Target::setAttr(typename AttributeTraits<A>::Type const& i_attrValue) } } +#ifdef __HOSTBOOT_MODULE +template<const ATTRIBUTE_ID A> +void Target::setAttrFromStdArr(typename AttributeTraits<A>::TypeStdArr const& + i_attrValue) +{ + bool l_wrote = trySetAttr<A>(i_attrValue); + if (unlikely(!l_wrote)) + { + targAssert(SET_ATTR_FROM_STD_ARR, A); + } +} +#endif + template<const ATTRIBUTE_ID A> mutex_t* Target::getHbMutexAttr() const { @@ -978,6 +1113,23 @@ const char* Target::getAttrAsString() const return attrToString<A>(l_attrValue); } +#ifdef __HOSTBOOT_MODULE +template<const ATTRIBUTE_ID A> +typename AttributeTraits<A>::TypeStdArr Target::getAttrAsStdArr() const +{ + typename AttributeTraits<A>::TypeStdArr l_stdArr; + + bool l_read = tryGetAttr<A>(l_stdArr); + + if (unlikely(!l_read)) + { + targAssert(GET_ATTR_AS_STD_ARRAY, A); + } + + return l_stdArr; +} +#endif + // Function to set various frequency related attributes /** * @brief - sets various attributes directly related to the nest frequency. diff --git a/src/usr/targeting/common/target.C b/src/usr/targeting/common/target.C index 15fedd006..3bb8ebd4a 100644 --- a/src/usr/targeting/common/target.C +++ b/src/usr/targeting/common/target.C @@ -745,6 +745,12 @@ void Target::targAssert(TargAssertReason i_reason, "TARGETING::Target::setAttr<0x%7x>: trySetAttr returned false", i_ffdc); break; + case SET_ATTR_FROM_STD_ARR: + TARG_ASSERT(false, + "TARGETING::Target::setAttrFromStdArr<0x%7x>: setAttrFromStdArr " + "returned false", + i_ffdc); + break; case GET_ATTR: TARG_ASSERT(false, "TARGETING::Target::getAttr<0x%7x>: tryGetAttr returned false", @@ -755,6 +761,12 @@ void Target::targAssert(TargAssertReason i_reason, "TARGETING::Target::getAttrAsString<0x%7x>: tryGetAttr returned false", i_ffdc); break; + case GET_ATTR_AS_STD_ARRAY: + TARG_ASSERT(false, + "TARGETING::Target::getAttrAsStdArray<0x%7x>: getAttrAsStdArray returned" + " false", + i_ffdc); + break; case GET_HB_MUTEX_ATTR: TARG_ASSERT(false, "TARGETING::Target::_getHbMutexAttr<0x%7x>: _getAttrPtr returned NULL", diff --git a/src/usr/targeting/common/xmltohb/xmltohb.pl b/src/usr/targeting/common/xmltohb/xmltohb.pl index b3370906e..1575bdc9e 100755 --- a/src/usr/targeting/common/xmltohb/xmltohb.pl +++ b/src/usr/targeting/common/xmltohb/xmltohb.pl @@ -1018,32 +1018,30 @@ sub validateAttributes { my($attributes) = @_; my %elements = ( ); - $elements{"id"} = { required => 1, isscalar => 1}; - $elements{"description"} = { required => 1, isscalar => 1}; - $elements{"persistency"} = { required => 1, isscalar => 1}; - $elements{"fspOnly"} = { required => 0, isscalar => 0}; - $elements{"hbOnly"} = { required => 0, isscalar => 0}; - $elements{"readable"} = { required => 0, isscalar => 0}; - $elements{"simpleType"} = { required => 0, isscalar => 0}; - $elements{"complexType"} = { required => 0, isscalar => 0}; - $elements{"nativeType"} = { required => 0, isscalar => 0}; - $elements{"writeable"} = { required => 0, isscalar => 0}; - $elements{"hasStringConversion"} - = { required => 0, isscalar => 0}; - $elements{"hwpfToHbAttrMap"} - = { required => 0, isscalar => 0}; - $elements{"display-name"} = { required => 0, isscalar => 1}; - $elements{"virtual"} = { required => 0, isscalar => 0}; - $elements{"tempAttribute"} = { required => 0, isscalar => 0}; - $elements{"serverwizReadonly"} = { required => 0, isscalar => 0}; - $elements{"serverwizShow"} = { required => 0, isscalar => 1}; - $elements{"global"} = { required => 0, isscalar => 0}; - $elements{"range"} = { required => 0, isscalar => 0}; - $elements{"ignoreEkb"} = { required => 0, isscalar => 0}; - $elements{"mrwRequired"} = { required => 0, isscalar => 0}; + $elements{"id"} = { required => 1, isscalar => 1}; + $elements{"description"} = { required => 1, isscalar => 1}; + $elements{"persistency"} = { required => 1, isscalar => 1}; + $elements{"fspOnly"} = { required => 0, isscalar => 0}; + $elements{"hbOnly"} = { required => 0, isscalar => 0}; + $elements{"readable"} = { required => 0, isscalar => 0}; + $elements{"simpleType"} = { required => 0, isscalar => 0}; + $elements{"complexType"} = { required => 0, isscalar => 0}; + $elements{"nativeType"} = { required => 0, isscalar => 0}; + $elements{"writeable"} = { required => 0, isscalar => 0}; + $elements{"hasStringConversion"} = { required => 0, isscalar => 0}; + $elements{"hwpfToHbAttrMap"} = { required => 0, isscalar => 0}; + $elements{"display-name"} = { required => 0, isscalar => 1}; + $elements{"virtual"} = { required => 0, isscalar => 0}; + $elements{"tempAttribute"} = { required => 0, isscalar => 0}; + $elements{"serverwizReadonly"} = { required => 0, isscalar => 0}; + $elements{"serverwizShow"} = { required => 0, isscalar => 1}; + $elements{"global"} = { required => 0, isscalar => 0}; + $elements{"range"} = { required => 0, isscalar => 0}; + $elements{"ignoreEkb"} = { required => 0, isscalar => 0}; + $elements{"mrwRequired"} = { required => 0, isscalar => 0}; # do NOT export attribute & its associated enum to serverwiz - $elements{"no_export"} = { required => 0, isscalar => 0}; + $elements{"no_export"} = { required => 0, isscalar => 0}; foreach my $attribute (@{$attributes->{attribute}}) { @@ -2438,6 +2436,9 @@ print $outFile <<VERBATIM; // STD #include <stdint.h> #include <stdlib.h> +#ifdef __HOSTBOOT_MODULE +#include <array> +#endif VERBATIM foreach my $attribute (@{$attributes->{attribute}}) @@ -2541,12 +2542,11 @@ sub writeTraitFileTraits { $traits .= " fspAccessible,"; } - chop($traits); - # Build value type my $type = ""; my $dimensions = ""; + my $stdArrAddOn = ""; # Only used if attr holds array type if(exists $attribute->{simpleType}) { my $simpleType = $attribute->{simpleType}; @@ -2569,11 +2569,26 @@ sub writeTraitFileTraits { if( (exists $simpleType->{array}) && ($simpleTypeProperties->{$typeName}{supportsArray}) ) { - my @bounds = split(/,/,$simpleType->{array}); - foreach my $bound (@bounds) + + my @revBounds = reverse split(/,/,$simpleType->{array}); + + for my $idx (0 .. $#revBounds) { - $dimensions .= "[$bound]"; + $dimensions = "[@revBounds[$idx]]$dimensions"; + + # Creating std::array, even if multi-dimensional + if ($idx == 0) + { + $stdArrAddOn = "std::array<$type, " + ."@revBounds[$idx]>"; + } + else + { + $stdArrAddOn = "std::array<$stdArrAddOn, " + ."@revBounds[$idx]>"; + } } + } if(exists $simpleType->{string}) @@ -2611,6 +2626,8 @@ sub writeTraitFileTraits { . "$attribute->{id}."); } + chop($traits); + # if it already exists skip it if( !exists($attrValHash{$attribute->{id}})) { @@ -2625,6 +2642,13 @@ sub writeTraitFileTraits { print $outFile " public:\n"; print $outFile " enum {",$traits," };\n"; print $outFile " typedef ", $type, " Type$dimensions;\n"; + if ($stdArrAddOn ne "") + { + # Append typedef for std::array if attr holds array value + print $outFile "#ifdef __HOSTBOOT_MODULE\n"; + print $outFile " typedef $stdArrAddOn TypeStdArr;\n"; + print $outFile "#endif\n"; + } print $outFile "};\n\n"; $typedefs .= "// Type aliases and/or sizes for ATTR_" @@ -2637,6 +2661,14 @@ sub writeTraitFileTraits { $typedefs .= "typedef " . $type . " ATTR_" . "$attribute->{id}" . "_type" . $dimensions . ";\n"; + if ($stdArrAddOn ne "") + { + $typedefs .= "#ifdef __HOSTBOOT_MODULE\n"; + $typedefs .= "typedef $stdArrAddOn " + ."ATTR_$attribute->{id}_typeStdArr;\n"; + $typedefs .= "#endif\n"; + } + # If a string, append max # of characters for the string if( (exists $attribute->{simpleType}) && (exists $attribute->{simpleType}->{string})) diff --git a/src/usr/targeting/test/testtargeting.H b/src/usr/targeting/test/testtargeting.H index 66bb940ca..9456f1dd5 100644 --- a/src/usr/targeting/test/testtargeting.H +++ b/src/usr/targeting/test/testtargeting.H @@ -147,6 +147,76 @@ void* funcTestRecursiveMutexEntry(void* i_pData) return nullptr; } +/** + * @brief Function to test get and set of std::array values for attributes that + * support it. Any N-th dimensional array can be tested. + * + * @param[in] i_target Pointer to target object + * @param[in] i_setVal TA_typeStdArr type value to set + */ +template <const TARGETING::ATTRIBUTE_ID TA, typename TA_typeStdArr, + typename TA_type> +void testStdArrayND(TARGETING::Target *i_target, TA_typeStdArr i_setVal) +{ + + // Storing original value + TA_type l_origVal; + + if(!i_target->tryGetAttr<TA>(l_origVal)) + { + TS_FAIL("Failed to get original value of attribute."); + return; + } + + // Setting value using std::array as input + i_target->setAttrFromStdArr<TA>(i_setVal); + + // Get c-style array + TA_type l_cArrOutVal; + if(!i_target->tryGetAttr<TA>(l_cArrOutVal)) + { + TS_FAIL("Could not get c-style array value of attribute."); + return; + } + + // Copying l_cArrOutVal to a std::array var so that it can be + // compared with l_outVal below + TA_typeStdArr l_cArrOutValStdArr; + memcpy(&l_cArrOutValStdArr, &l_cArrOutVal, sizeof(l_cArrOutVal)); + + // std::array output + auto l_outVal = i_target->getAttrAsStdArr<TA>(); + + // Comparing set value with std::array value, and std::array value with + // c-array value + if (l_outVal == i_setVal) + { + TS_INFO("Success, get value equals set value."); + if (l_cArrOutValStdArr == l_outVal) + { + TS_INFO("Success, get c-style array value equals get std::array" + " value."); + } + else + { + TS_FAIL("Failure, get c-style array value does not equal get" + " std::array value."); + } + } + else + { + TS_FAIL("Failure, get value does not equal set value."); + } + + // Restoring original value + if(!i_target->trySetAttr<TA>(l_origVal)) + { + TS_FAIL("Failed to restore original attribute value."); + } + +} + + class TargetingTestSuite : public CxxTest::TestSuite { public: @@ -489,6 +559,59 @@ class TargetingTestSuite : public CxxTest::TestSuite TS_TRACE(EXIT_MRK "testSignedAttribute"); } + /** + * @brief Testing attribute's ability to get/set using std::array + */ + void testStdArray() + { + + // Testing 1D array + + TS_INFO(ENTER_MRK "testStdArray: Testing 1D array"); + + constexpr auto TA = TARGETING::ATTR_IPC_NODE_BUFFER_GLOBAL_ADDRESS; + // TA: targeting attribute + typedef TARGETING::ATTR_IPC_NODE_BUFFER_GLOBAL_ADDRESS_typeStdArr + TA_typeStdArr; + typedef TARGETING::ATTR_IPC_NODE_BUFFER_GLOBAL_ADDRESS_type TA_type; + + TARGETING::Target* l_pTarget = nullptr; + TARGETING::targetService().getTopLevelTarget(l_pTarget); + assert(l_pTarget != nullptr, "testStdArray, unable to establish top" + " level target service"); + + TA_typeStdArr l_setVal = {9, 6, 3, 1, 5, 1, 7, 3}; + + testStdArrayND<TA, TA_typeStdArr, TA_type>(l_pTarget, l_setVal); + + // Testing 2D array + TS_INFO(ENTER_MRK "testStdArray: Testing 2D array"); + + constexpr auto TA2 = TARGETING::ATTR_EEPROM_PAGE_ARRAY; + typedef TARGETING::ATTR_EEPROM_PAGE_ARRAY_typeStdArr TA2_typeStdArr; + typedef TARGETING::ATTR_EEPROM_PAGE_ARRAY_type TA2_type; + + TARGETING::TargetHandleList l_procList; + TARGETING::getAllChips(l_procList, TARGETING::TYPE_PROC); + + if (l_procList.size() == 0 ) + { + TS_FAIL("Failed to get proc targets."); + } + else + { + // Setting value using std::array as input + TA2_typeStdArr l_setVal2 {{ {9, 6, 3, 1}, {8, 4, 2, 44}, + {18, 14, 22, 2}, {77, 8, 6, 54} }}; + + testStdArrayND<TA2, TA2_typeStdArr, TA2_type>(l_procList.front(), + l_setVal2); + } + + TS_INFO(EXIT_MRK "testStdArray"); + + } + void testPciPhbTarget() { TS_TRACE(ENTER_MRK "testPciPhbTarget" ); |

