diff options
Diffstat (limited to 'src/usr/targeting')
-rwxr-xr-x | src/usr/targeting/attrrp_common.C | 10 | ||||
-rw-r--r-- | src/usr/targeting/attrsync.C | 19 | ||||
-rw-r--r-- | src/usr/targeting/common/target.C | 44 | ||||
-rw-r--r-- | src/usr/targeting/common/targetservice.C | 125 | ||||
-rwxr-xr-x | src/usr/targeting/common/xmltohb/xmltohb.pl | 53 | ||||
-rw-r--r-- | src/usr/targeting/runtime/attrrp_rt.C | 94 | ||||
-rw-r--r-- | src/usr/targeting/runtime/makefile | 1 | ||||
-rw-r--r-- | src/usr/targeting/runtime/rt_targeting.C | 532 |
8 files changed, 864 insertions, 14 deletions
diff --git a/src/usr/targeting/attrrp_common.C b/src/usr/targeting/attrrp_common.C index 4406182a3..693d421a3 100755 --- a/src/usr/targeting/attrrp_common.C +++ b/src/usr/targeting/attrrp_common.C @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2013,2016 */ +/* Contributors Listed Below - COPYRIGHT 2013,2017 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -56,9 +56,15 @@ namespace TARGETING } #ifndef __HOSTBOOT_RUNTIME msg_q_destroy(iv_msgQ); + TARG_ASSERT(false, "Assert to exit ~AttrRP"); +#else + // Only assert if this in not a temporary AttrRP instance + if (!iv_isTempInstance) + { + TARG_ASSERT(false, "Assert to exit ~AttrRP"); + } #endif - TARG_ASSERT(false, "Assert to exit ~AttrRP"); } void AttrRP::init(errlHndl_t &io_taskRetErrl, bool i_isMpipl) diff --git a/src/usr/targeting/attrsync.C b/src/usr/targeting/attrsync.C index 4201776be..b184e9abe 100644 --- a/src/usr/targeting/attrsync.C +++ b/src/usr/targeting/attrsync.C @@ -61,6 +61,7 @@ namespace TARGETING } +#ifndef __HOSTBOOT_RUNTIME ATTR_SYNC_RC AttributeSync::updateSectionData() const { TARG_INF( ENTER_MRK "AttributeSync::updateSectionData - " @@ -90,6 +91,23 @@ namespace TARGETING return l_rc; } +#else + std::vector<TARGETING::sectionRefData> AttributeSync::syncSectionFromAttrRP( + TARGETING::SECTION_TYPE i_section_to_sync) + { + iv_section_to_sync = i_section_to_sync; + + do + { + // set up the pointers to the data area + getSectionData(); + } while(0); + + return iv_pages; + } +#endif + +#ifndef __HOSTBOOT_RUNTIME errlHndl_t AttributeSync::syncSectionToFsp( TARGETING::SECTION_TYPE i_section_to_sync ) { @@ -625,6 +643,7 @@ namespace TARGETING TARG_INF( EXIT_MRK "syncAllAttributesFromFsp" ); return l_errl; } +#endif }; // end namespace diff --git a/src/usr/targeting/common/target.C b/src/usr/targeting/common/target.C index 49e94e820..b48827187 100644 --- a/src/usr/targeting/common/target.C +++ b/src/usr/targeting/common/target.C @@ -276,6 +276,50 @@ void Target::_getAttrPtr( } //****************************************************************************** +// Target::_getAttrPtr +//****************************************************************************** + +void Target::_getAttrPtr( + ATTRIBUTE_ID i_attr, + AttrRP* i_attrRP, + ATTRIBUTE_ID* i_pAttrId, + AbstractPointer<void>* i_ppAttrAddr, + void*& o_pAttr) const +{ + + #define TARG_FN "_getAttrPtr()" + + void* l_pAttr = NULL; + + // Search for the attribute ID. + ATTRIBUTE_ID* ptr = std::lower_bound(i_pAttrId, + i_pAttrId + iv_attrs, + i_attr); + if ((ptr != i_pAttrId + iv_attrs) && (*ptr == i_attr)) + { + // Locate the corresponding attribute address + l_pAttr = + TARG_TO_PLAT_PTR(*(i_ppAttrAddr + std::distance(i_pAttrId, ptr))); + + // Only translate addresses on platforms where addresses are + // 4 byte wide (FSP). The compiler should perform dead code + // elimination this path on platforms with 8 byte wide + // addresses (Hostboot), since the "if" check can be statically + // computed at compile time. + if(TARG_ADDR_TRANSLATION_REQUIRED) + { + l_pAttr = + i_attrRP->translateAddr(l_pAttr, + static_cast<const Target*>(this)); + } + } + + o_pAttr = l_pAttr; + + #undef TARG_FN +} + +//****************************************************************************** // Target::_getHbMutexAttr //****************************************************************************** diff --git a/src/usr/targeting/common/targetservice.C b/src/usr/targeting/common/targetservice.C index b47b4a6b7..917bd5258 100644 --- a/src/usr/targeting/common/targetservice.C +++ b/src/usr/targeting/common/targetservice.C @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2012,2016 */ +/* Contributors Listed Below - COPYRIGHT 2012,2017 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -1085,12 +1085,16 @@ void TargetService::readSectionData( //****************************************************************************** void TargetService::_configureTargetPool( - NodeSpecificInfo& i_nodeInfoContainer) + NodeSpecificInfo& i_nodeInfoContainer, + AttrRP *i_attrRP) { #define TARG_FN "_configureTargetPool(...)" TARG_ENTER(); + AttrRP *l_attrRP = (i_attrRP == NULL) + ? &TARG_GET_SINGLETON(TARGETING::theAttrRP) : i_attrRP; + _maxTargets(i_nodeInfoContainer); // iv_pPnor--> points to uint32_t* --> points to --> uint32_t, targets[] @@ -1114,7 +1118,7 @@ void TargetService::_configureTargetPool( if(TARG_ADDR_TRANSLATION_REQUIRED) { i_nodeInfoContainer.targets = static_cast<Target(*)[]>( - TARG_GET_SINGLETON(TARGETING::theAttrRP).translateAddr( + l_attrRP->translateAddr( i_nodeInfoContainer.targets, i_nodeInfoContainer.nodeId)); TARG_ASSERT(i_nodeInfoContainer.targets, TARG_ERR_LOC "FATAL: Could not determine location of targets after " @@ -1132,10 +1136,14 @@ void TargetService::_configureTargetPool( // TargetService::_maxTargets //****************************************************************************** -void TargetService::_maxTargets(NodeSpecificInfo& io_nodeInfoContainer) +void TargetService::_maxTargets(NodeSpecificInfo& io_nodeInfoContainer, + AttrRP *i_attrRP) { #define TARG_FN "_maxTargets(...)" + AttrRP *l_attrRP = (i_attrRP == NULL) + ? &TARG_GET_SINGLETON(TARGETING::theAttrRP) : i_attrRP; + // Target count found by following the pointer pointed to by the iv_pPnor // pointer. const AbstractPointer<uint32_t>* pNumTargetsPtr @@ -1149,8 +1157,8 @@ void TargetService::_maxTargets(NodeSpecificInfo& io_nodeInfoContainer) // can be statically computed at compile time. if(TARG_ADDR_TRANSLATION_REQUIRED) { - pNumTargets = static_cast<uint32_t*>( - TARG_GET_SINGLETON(TARGETING::theAttrRP).translateAddr( + pNumTargets = + static_cast<uint32_t*>(l_attrRP->translateAddr( pNumTargets, io_nodeInfoContainer.nodeId)); } @@ -1393,6 +1401,111 @@ void TargetService::getMasterNodeTarget( #undef TARG_FN } +//****************************************************************************** +// TargetService::getTargetRangeFilter +//****************************************************************************** + +TargetRangeFilter TargetService::getTargetRangeFilter(void *i_attrData, + AttrRP *i_attrRP, + uint32_t &o_maxTargets, + NODE_ID i_nodeId) +{ + #define TARG_FN "getTargetRangeFilter(...)" + TARG_ENTER(); + + // Get pointer to TargetingHeader for attribute data + TargetingHeader* l_header = + reinterpret_cast<TargetingHeader*>(i_attrData); + + // Verify TargetingHeader + TARG_ASSERT(l_header != NULL, TARG_ERR_LOC + "TargetingHeader for attribute data is NULL"); + TARG_ASSERT(l_header->eyeCatcher == PNOR_TARG_EYE_CATCHER, TARG_ERR_LOC + "TargetingHeader eyecatcher 0x%16llX is incorrect", + l_header->eyeCatcher) + + // Create node info + TargetService::NodeSpecificInfo l_nodeSpecificInfo; + l_nodeSpecificInfo.nodeId = i_nodeId; + + // Save away the address of the targeting data in pPnor field + l_nodeSpecificInfo.pPnor = + reinterpret_cast<uint32_t*>(reinterpret_cast<char*>(l_header) + + l_header->headerSize); + + (void)TargetService::_configureTargetPool(l_nodeSpecificInfo, + i_attrRP); + + l_nodeSpecificInfo.initialized = true; + + // Create pointer to first target in new attribute data + // First target is after header and number of targets count + Target* l_pFirstTarget = &(*(l_nodeSpecificInfo.targets))[0]; + TARG_INF("getTargetRangeFilter: First target pointer %p, huid 0x%.8x", + l_pFirstTarget, + get_huid(l_pFirstTarget)); + + // Create TargetRangeFilter for attribute data + TargetRangeFilter l_rangeFilter(TargetIterator(l_pFirstTarget), + TargetIterator(NULL), + NULL); + + // Set maximum target value to be returned + o_maxTargets = l_nodeSpecificInfo.maxTargets; + + TARG_EXIT(); + #undef TARG_FN + + return l_rangeFilter; +} + +//****************************************************************************** +// TargetService::getTargetAttributes +//****************************************************************************** + +uint32_t TargetService::getTargetAttributes(Target*i_target, + AttrRP *i_attrRP, + ATTRIBUTE_ID* &o_pAttrId, + AbstractPointer<void>* + &o_ppAttrAddr) +{ + #define TARG_FN "getTargetAttributes(...)" + // TARG_ENTER(); + + // Transform platform neutral pointers into platform specific pointers, and + // optimize processing by not having to do the conversion in the loop below + // (it's guaranteed that attribute metadata will be in the same contiguous + // VMM region) + o_pAttrId = TARG_TO_PLAT_PTR(i_target->iv_pAttrNames); + o_ppAttrAddr = TARG_TO_PLAT_PTR(i_target->iv_pAttrValues); + TARG_DBG("o_pAttrId before translation = %p, " + "o_ppAttrAddr before translation = %p", + o_pAttrId, + o_ppAttrAddr); + + // Only translate addresses on platforms where addresses are 4 bytes wide + // (FSP). The compiler should perform dead code elimination of this path on + // platforms with 8 byte wide addresses (Hostboot), since the "if" check can + // be statically computed at compile time. + if(TARG_ADDR_TRANSLATION_REQUIRED) + { + o_pAttrId = static_cast<ATTRIBUTE_ID*>( + i_attrRP->translateAddr(o_pAttrId, i_target)); + o_ppAttrAddr = static_cast<AbstractPointer<void>*>( + i_attrRP->translateAddr(o_ppAttrAddr, i_target)); + TARG_DBG("o_pAttrId after translation = %p, " + "o_ppAttrAddr after translation = %p", + o_pAttrId, + o_ppAttrAddr); + } + + // TARG_EXIT(); + #undef TARG_FN + + // Return the number of attributes for this target + return i_target->iv_attrs; +} + #undef TARG_CLASS #undef TARG_NAMESPACE diff --git a/src/usr/targeting/common/xmltohb/xmltohb.pl b/src/usr/targeting/common/xmltohb/xmltohb.pl index fc45c0280..fc1392e5f 100755 --- a/src/usr/targeting/common/xmltohb/xmltohb.pl +++ b/src/usr/targeting/common/xmltohb/xmltohb.pl @@ -2325,6 +2325,7 @@ sub writeTraitFileTraits { my($attributes,$outFile) = @_; my $typedefs = ""; + my $sizefunc = ""; my %attrValHash; @@ -2450,14 +2451,14 @@ sub writeTraitFileTraits { print $outFile "};\n\n"; $typedefs .= "// Type aliases and/or sizes for ATTR_" - . "$attribute->{id} attribute\n"; + . "$attribute->{id} attribute\n"; $typedefs .= "typedef " . $type . - " $attribute->{id}" . "_ATTR" . $dimensions . ";\n"; + " $attribute->{id}" . "_ATTR" . $dimensions . ";\n"; # Append a more friendly type alias for attribute $typedefs .= "typedef " . $type . - " ATTR_" . "$attribute->{id}" . "_type" . $dimensions . ";\n"; + " ATTR_" . "$attribute->{id}" . "_type" . $dimensions . ";\n"; # If a string, append max # of characters for the string if( (exists $attribute->{simpleType}) @@ -2465,11 +2466,21 @@ sub writeTraitFileTraits { { my $size = $attribute->{simpleType}->{string}->{sizeInclNull}-1; $typedefs .= "const size_t ATTR_" - . "$attribute->{id}" . "_max_chars = " - . "$size" - . ";\n"; + . "$attribute->{id}" . "_max_chars = " + . "$size" + . ";\n"; } $typedefs .= "\n"; + + # Create case definitions for attrSizeLookup function + + $sizefunc .= " // Get size for ATTR_$attribute->{id}" . + " attribute\n"; + $sizefunc .= " case ATTR_$attribute->{id}:\n"; + $sizefunc .= " l_attrSize = sizeof(ATTR_" . + "$attribute->{id}_type);\n"; + $sizefunc .= " break;\n"; + $sizefunc .= "\n"; } }; @@ -2477,6 +2488,36 @@ sub writeTraitFileTraits { print $outFile wrapBrief("Mapping of alias type name to underlying type"); print $outFile " */\n"; print $outFile $typedefs ."\n"; + + # Create attrSizeLookup function + + print $outFile <<VERBATIM; +/** + * \@brief Function to return size of specified attribute + * + * \@param[in] i_attrId Attribute ID for attribute to look up size + * \@return uint32_t Size of the attribute + * + * \@retval Size of the attribute if succeeded + * \@retval 0 if failed + * + */ +inline uint32_t attrSizeLookup(ATTRIBUTE_ID i_attrId) +{ + uint32_t l_attrSize = 0; + + switch(i_attrId) { +VERBATIM + print $outFile $sizefunc; + print $outFile <<VERBATIM; + default: + break; + } + + return l_attrSize; +} + +VERBATIM } ################################################################################ diff --git a/src/usr/targeting/runtime/attrrp_rt.C b/src/usr/targeting/runtime/attrrp_rt.C index 7262c0f5a..f0557fd64 100644 --- a/src/usr/targeting/runtime/attrrp_rt.C +++ b/src/usr/targeting/runtime/attrrp_rt.C @@ -29,6 +29,7 @@ #include <errl/errlentry.H> #include <targeting/common/targreasoncodes.H> #include <targeting/targplatreasoncodes.H> +#include <targeting/attrsync.H> #include <util/runtime/util_rt.H> #include "../attrrp_common.C" @@ -37,6 +38,98 @@ using namespace ERRORLOG; namespace TARGETING { + void AttrRP::fillInAttrRP(TargetingHeader* i_header) + { + TRACFCOMP(g_trac_targeting, ENTER_MRK"AttrRP::fillInAttrRP"); + + do + { + // Create AttributeSync + AttributeSync l_attributeSync = AttributeSync(); + + // Allocate section structures based on section count in header. + iv_sectionCount = i_header->numSections; + iv_sections = new AttrRP_Section[iv_sectionCount](); + + // Find start to the first section: + // (header address + size of header + offset in header) + TargetingSection* l_section = + reinterpret_cast<TargetingSection*>( + reinterpret_cast<uint64_t>(i_header) + + sizeof(TargetingHeader) + i_header->offsetToSections + ); + + uint64_t l_offset = 0; + + for (size_t i = 0; i < iv_sectionCount; ++i, ++l_section) + { + iv_sections[i].type = l_section->sectionType; + iv_sections[i].size = l_section->sectionSize; + + iv_sections[i].vmmAddress = + static_cast<uint64_t>( + TARG_TO_PLAT_PTR(i_header->vmmBaseAddress)) + + i_header->vmmSectionOffset*i; + iv_sections[i].pnorAddress = + reinterpret_cast<uint64_t>(i_header) + l_offset; + + l_offset += ALIGN_PAGE(iv_sections[i].size); + + TRACFCOMP(g_trac_targeting, + "Decoded Attribute Section: %d, 0x%lx, 0x%lx, 0x%lx", + iv_sections[i].type, + iv_sections[i].vmmAddress, + iv_sections[i].pnorAddress, + iv_sections[i].size); + } + + for (size_t i = 0; i < iv_sectionCount; ++i) + { + // get section data from current AttrRP + std::vector <TARGETING::sectionRefData>l_pages; + l_pages = + l_attributeSync.syncSectionFromAttrRP(iv_sections[i].type); + + // write section data to new AttrRP + uint8_t * l_dataPtr = nullptr; // ptr to Attribute address space + bool l_rc = true; // true if write is successful + + // for each page + for(std::vector<TARGETING::sectionRefData>::const_iterator + pageIter = l_pages.begin(); + (pageIter != l_pages.end()) && (true == l_rc); + ++pageIter) + { + // check that page number is within range + uint64_t l_pageOffset = (*pageIter).pageNumber * PAGESIZE; + if ( iv_sections[i].size < (l_pageOffset + PAGESIZE) ) + { + TARG_ERR("page offset 0x%lx is greater than " + "size 0x%lx of section %u", + l_pageOffset, + iv_sections[i].size, + iv_sections[i].type); + + l_rc = false; + break; + } + + // adjust the pointer out by page size * page number + l_dataPtr = + reinterpret_cast<uint8_t *>(iv_sections[i].pnorAddress) + + l_pageOffset; + + memcpy( l_dataPtr, (*pageIter).dataPtr, PAGESIZE ); + + } + } + } while(false); + + TRACFCOMP(g_trac_targeting, EXIT_MRK"AttrRP::fillInAttrRP"); + + return; + } + void AttrRP::startup(errlHndl_t& io_taskRetErrl, bool isMpipl) { TRACFCOMP(g_trac_targeting, "AttrRP::startup"); @@ -49,6 +142,7 @@ namespace TARGETING reinterpret_cast<TargetingHeader*>( hb_get_rt_rsvd_mem(Util::HBRT_MEM_LABEL_ATTR,0,attr_size)); + if ((NULL == l_header) || (l_header->eyeCatcher != PNOR_TARG_EYE_CATCHER)) { diff --git a/src/usr/targeting/runtime/makefile b/src/usr/targeting/runtime/makefile index b453a1f99..c2279f8b2 100644 --- a/src/usr/targeting/runtime/makefile +++ b/src/usr/targeting/runtime/makefile @@ -40,6 +40,7 @@ HOSTBOOT_RUNTIME_SPECIFIC_OBJS += rt_targeting.o HOSTBOOT_RUNTIME_SPECIFIC_OBJS += attrPlatOverride_rt.o HOSTBOOT_RUNTIME_SPECIFIC_OBJS += errludattribute.o HOSTBOOT_RUNTIME_SPECIFIC_OBJS += attributestrings.o +HOSTBOOT_RUNTIME_SPECIFIC_OBJS += attrsync.o OBJS += ${COMMON_TARGETING_OBJS} OBJS += ${HOSTBOOT_RT_IPL_COMMON_OBJS} diff --git a/src/usr/targeting/runtime/rt_targeting.C b/src/usr/targeting/runtime/rt_targeting.C index 96a024ffe..3b2d64ecd 100644 --- a/src/usr/targeting/runtime/rt_targeting.C +++ b/src/usr/targeting/runtime/rt_targeting.C @@ -34,12 +34,16 @@ #include <targeting/common/utilFilter.H> #include <targeting/common/trace.H> #include <targeting/common/targreasoncodes.H> +#include <targeting/common/attributeTank.H> +#include <targeting/attrrp.H> #include <arch/pirformat.H> #include <runtime/customize_attrs_for_payload.H> #include <runtime/rt_targeting.H> #include <runtime/interface.h> #include <map> #include <util/memoize.H> +#include <util/runtime/util_rt.H> +#include <util/utillidmgr.H> using namespace TARGETING; @@ -172,9 +176,537 @@ errlHndl_t getHbTarget( return Util::Memoize::memoize(_getHbTarget,i_rtTargetId,o_target); } +/** + * @brief Validate LID Structure against Reserved Memory. Check that the + * TargetingHeader eyecatchers are valid, that the TargetingHeader number of + * sections match, and that the types and sizes of each TargetingSection match. + * @param[in] Pointer to new LID Structure targeting binary data + * @param[in] Pointer to current Reserved Memory targeting binary data + * @return 0 on success, else return code + */ +int validateData(void *i_lidStructPtr, + void *i_rsvdMemPtr) +{ + TRACFCOMP(g_trac_targeting,ENTER_MRK"validateData"); + + int rc = 0; + + do + { + // Get pointers to TargetingHeader areas of each buffer + TargetingHeader* l_headerLid = + reinterpret_cast<TargetingHeader*>(i_lidStructPtr); + TargetingHeader* l_headerRsvd = + reinterpret_cast<TargetingHeader*>(i_rsvdMemPtr); + + // Find start to the first section in each buffer: + // (header address + size of header + offset in header) + TargetingSection* l_sectionLid = + reinterpret_cast<TargetingSection*>( + reinterpret_cast<uint64_t>(l_headerLid) + + sizeof(TargetingHeader) + + l_headerLid->offsetToSections); + TargetingSection* l_sectionRsvd = + reinterpret_cast<TargetingSection*>( + reinterpret_cast<uint64_t>(l_headerRsvd) + + sizeof(TargetingHeader) + + l_headerRsvd->offsetToSections); + + // Validate LID Structure TargetingHeader eyecatcher + if (l_headerLid->eyeCatcher != PNOR_TARG_EYE_CATCHER) + { + TRACFCOMP(g_trac_targeting, + "validateData: bad eyecatcher 0x%.8x found in " + "LID Structure TargetingHeader", + l_headerLid->eyeCatcher); + + rc = 1; + + break; + } + + // Validate Reserved Memory TargetingHeader eyecatcher + if (l_headerRsvd->eyeCatcher != PNOR_TARG_EYE_CATCHER) + { + TRACFCOMP(g_trac_targeting, + "validateData: bad eyecatcher 0x%.8x found in " + "Reserved Memory TargetingHeader", + l_headerRsvd->eyeCatcher); + + rc = 1; + + break; + } + + // Validate TargetingHeader number of sections + if (l_headerLid->numSections != l_headerRsvd->numSections) + { + TRACFCOMP(g_trac_targeting, + "validateData: TargetingHeader number of sections " + "miscompare, %d LID Structure sections,%d Reserved " + "Memory sections", + l_headerLid->numSections, + l_headerRsvd->numSections); + + rc = 1; + + break; + } + + // Count of attribute sections + size_t l_sectionCount = l_headerLid->numSections; + + // Loop on each TargetingSection + for (size_t i = 0; + i < l_sectionCount; + ++i, ++l_sectionLid, ++l_sectionRsvd) + { + // Validate TargetingSection type + if (l_sectionLid->sectionType != l_sectionRsvd->sectionType) + { + TRACFCOMP(g_trac_targeting, + "validateData: TargetingSection types miscompare, " + "LID Struct type 0x%0.4x, Rsvd Memory type 0x%0.4x", + l_sectionLid->sectionType, + l_sectionRsvd->sectionType); + + rc = 1; + + break; + } + + // Validate TargetingSection size + if (l_sectionLid->sectionSize != l_sectionRsvd->sectionSize) + { + TRACFCOMP(g_trac_targeting, + "validateData: TargetingSection sizes miscompare, " + "LID Struct size 0x%0.4x, Rsvd Memory size 0x%0.4x", + l_sectionLid->sectionSize, + l_sectionRsvd->sectionSize); + + // Just trace the size mismatch; Don't set rc or break + } + } + // *** Could check if rc was set in for loop and break from do loop + } while(false); + + TRACFCOMP(g_trac_targeting,EXIT_MRK"validateData"); + + return rc; +} + +/** + * @brief Save/Restore attribute values from current Reserved Memory data + * into new LID Structure data + * @param[in] Pointer to current Reserved Memory targeting binary data + * @param[in/out] Pointer to new LID Structure targeting binary data + * @return 0 on success, else return code + */ +int saveRestoreAttrs(void *i_rsvdMemPtr, + void *io_lidStructPtr) +{ + TRACFCOMP( g_trac_targeting, + ENTER_MRK"saveRestoreAttrs: %p %p", + i_rsvdMemPtr, io_lidStructPtr); + + int rc = 0; + AttrRP *l_attrRPLid = nullptr; + + do + { + // Node ID + NODE_ID l_nodeId = 0; + + // Locate current Reserved Memory data via TargetService + TARGETING::TargetService l_targSrv; + (void)l_targSrv.init(); + AttrRP *l_attrRPRsvd = &TARG_GET_SINGLETON(TARGETING::theAttrRP); + + // Create temporary AttrRP instance for new LID Structure targeting data + l_attrRPLid = + new AttrRP(reinterpret_cast<TargetingHeader*>(io_lidStructPtr)); + + // Create TargetRangeFilter for LID Structure targeting data + uint32_t l_maxTargetsLid = 0; + TargetRangeFilter l_allTargetsLid = + l_targSrv.getTargetRangeFilter(io_lidStructPtr, + l_attrRPLid, + l_maxTargetsLid, + l_nodeId); + + // Set up variables for getting attribute information for a target + uint32_t l_attrCountRsvd = 0; + ATTRIBUTE_ID* l_pAttrIdRsvd = nullptr; + AbstractPointer<void>* l_ppAttrAddrRsvd = nullptr; + uint32_t l_attrCountLid = 0; + ATTRIBUTE_ID* l_pAttrIdLid = nullptr; + AbstractPointer<void>* l_ppAttrAddrLid = nullptr; + uint32_t l_huidLid = 0; + EntityPath l_physPathLid; + + // Walk through new LID Structure Targets + for(uint32_t l_targetNum = 1; + (l_targetNum <= l_maxTargetsLid) && (rc == 0); + ++l_allTargetsLid, ++l_targetNum) + { + // Get attribute information for a target in LID Structure (new) + l_attrCountLid = l_targSrv.getTargetAttributes(*l_allTargetsLid, + l_attrRPLid, + l_pAttrIdLid, + l_ppAttrAddrLid); + + // Make sure that attributes were found + if(l_attrCountLid == 0) + { + // Continue to next target if there were no attributes + continue; + } + + l_huidLid = l_allTargetsLid->getAttr<ATTR_HUID>(); + if(l_huidLid != 0) + { + TRACFCOMP( g_trac_targeting, + "saveRestoreAttrs: target %3d has %3d attrs, " + "class %0.8x, type %0.8x, ordinal ID %0.8x, HUID " + "0x%0.8x", + l_targetNum, + l_attrCountLid, + l_allTargetsLid->getAttr<ATTR_CLASS>(), + l_allTargetsLid->getAttr<ATTR_TYPE>(), + l_allTargetsLid->getAttr<ATTR_ORDINAL_ID>(), + l_huidLid); + } + else + { + l_physPathLid = l_allTargetsLid->getAttr<ATTR_PHYS_PATH>(); + TRACFCOMP( g_trac_targeting, + "saveRestoreAttrs: target %3d has %3d attrs, " + "class %0.8x, type %0.8x, ordinal ID %0.8x, %s", + l_targetNum, + l_attrCountLid, + l_allTargetsLid->getAttr<ATTR_CLASS>(), + l_allTargetsLid->getAttr<ATTR_TYPE>(), + l_allTargetsLid->getAttr<ATTR_ORDINAL_ID>(), + l_physPathLid.toString()); + } + + // Create bool used while checking if target exists in current data + bool targetMatched = false; + + // Create TargetRangeFilter for current Reserved Memory data + TargetRangeFilter l_allTargetsRsvd(l_targSrv.begin(), + l_targSrv.end(), + NULL); + + // Walk through current Reserved Memory Targets + for(; + l_allTargetsRsvd; + ++l_allTargetsRsvd) + { + if((l_huidLid != 0) && + (l_allTargetsLid->getAttr<ATTR_CLASS>() == + l_allTargetsRsvd->getAttr<ATTR_CLASS>()) && + (l_allTargetsLid->getAttr<ATTR_TYPE>() == + l_allTargetsRsvd->getAttr<ATTR_TYPE>()) && + (l_allTargetsLid->getAttr<ATTR_ORDINAL_ID>() == + l_allTargetsRsvd->getAttr<ATTR_ORDINAL_ID>()) && + (l_huidLid == l_allTargetsRsvd->getAttr<ATTR_HUID>())) + { + // Flag the match + targetMatched = true; + + break; + } + else if((l_huidLid == 0) && + (l_allTargetsLid->getAttr<ATTR_CLASS>() == + l_allTargetsRsvd->getAttr<ATTR_CLASS>()) && + (l_allTargetsLid->getAttr<ATTR_TYPE>() == + l_allTargetsRsvd->getAttr<ATTR_TYPE>()) && + (l_allTargetsLid->getAttr<ATTR_ORDINAL_ID>() == + l_allTargetsRsvd->getAttr<ATTR_ORDINAL_ID>()) && + (l_physPathLid == + l_allTargetsRsvd->getAttr<ATTR_PHYS_PATH>())) + { + // Flag the match + targetMatched = true; + + break; + } + } + + // Check if target was matched up + if(!targetMatched) + { + if(l_huidLid != 0) + { + TRACFCOMP( g_trac_targeting, + "saveRestoreAttrs: Did not find target " + "HUID 0x%0.8x in Reserved Memory, " + "Keeping targeting data from LID Structure", + l_huidLid); + } + else + { + TRACFCOMP( g_trac_targeting, + "saveRestoreAttrs: Did not find target " + "%s in Reserved Memory, " + "Keeping targeting data from LID Structure", + l_physPathLid.toString()); + } + + // rc should not be changed + + // Go to next new LID Structure target + continue; + } + + // Get attribute information for a target in Reserved Memory (cur) + l_attrCountRsvd = l_targSrv.getTargetAttributes(*l_allTargetsRsvd, + l_attrRPRsvd, + l_pAttrIdRsvd, + l_ppAttrAddrRsvd); + TRACDCOMP( g_trac_targeting, + "Rsvd Memory: " + "HUID 0x%0.8x, attr cnt %d, AttrRP %p, pAttrId %p, " + "ppAttrAddr %p", + l_allTargetsRsvd->getAttr<ATTR_HUID>(), + l_attrCountRsvd, + l_attrRPRsvd, + l_pAttrIdRsvd, + l_ppAttrAddrRsvd); + + // Compare attribute counts for new LID Structure target and current + // Reserved Memory target to see if they differ or not + if(l_attrCountLid != l_attrCountRsvd) + { + // Trace when the attribute counts differ + TRACFCOMP( g_trac_targeting, + "saveRestoreAttrs: Attribute counts for target with " + "huid 0x%0.8x differ, LID Structure count %d, " + "Reserved Memory count %d", + l_huidLid, + l_attrCountLid, + l_attrCountRsvd); + } + + // Walk through Attributes for the new LID Structure target + for(uint32_t l_attrNumLid = 0; + (l_attrNumLid < l_attrCountLid) && (rc == 0); + ++l_attrNumLid) + { + // Get ID for attribute on this pass through loop + ATTRIBUTE_ID* l_pAttrId = l_pAttrIdLid + l_attrNumLid; + + // Get the Reserved Memory attribute value pointer + void* l_pAttrRsvd = nullptr; + l_allTargetsRsvd->_getAttrPtr(*l_pAttrId, + l_attrRPRsvd, + l_pAttrIdRsvd, + l_ppAttrAddrRsvd, + l_pAttrRsvd); + + // Check if attribute is in Reserved Memory data + if(l_pAttrRsvd != nullptr) + { + // Get the LID Structure attribute value pointer + void* l_pAttrLid = nullptr; + l_allTargetsLid->_getAttrPtr(*l_pAttrId, + l_attrRPLid, + l_pAttrIdLid, + l_ppAttrAddrLid, + l_pAttrLid); + + // Look up the size of the attribute + uint32_t l_attrSize = attrSizeLookup(*l_pAttrId); + + // Check that attribute has a valid size + if(l_attrSize == 0) + { + TRACFCOMP( g_trac_targeting, + "saveRestoreAttrs: Did not find size of " + "attribute for attribute ID 0x%.8x, target " + "huid 0x%0.8x in Reserved Memory", + *l_pAttrId, + l_allTargetsRsvd->getAttr<ATTR_HUID>()); + + rc = 1; + + break; + } + + // Check if new attribute value differs from current value + if(memcmp(l_pAttrRsvd, l_pAttrLid, l_attrSize) != 0) + { + TRACFCOMP( g_trac_targeting, + "saveRestoreAttrs: Found differing values " + "for attribute ID 0x%.8x, huid 0x%0.8x", + *l_pAttrId, + l_huidLid); + + TRACFBIN( g_trac_targeting, + "saveRestoreAttrs: Reserved Memory value", + l_pAttrRsvd, + l_attrSize); + + TRACFBIN( g_trac_targeting, + "saveRestoreAttrs: LID Structure value", + l_pAttrLid, + l_attrSize); + + // Copy attribute value from current Reserved Memory + // attribute to new LID Structure attribute + memcpy(l_pAttrRsvd, l_pAttrLid, l_attrSize); + } + } + else + { + TRACFCOMP( g_trac_targeting, + "saveRestoreAttrs: Did not find attribute ID " + "0x%.8x, target huid 0x%0.8x in Reserved " + "Memory, Keeping value from LID Structure", + *l_pAttrId, + l_huidLid); + + // rc should not be changed + } + } // for attributes + } // for targets + } while(false); + + delete l_attrRPLid; + l_attrRPLid = nullptr; + + TRACFCOMP( g_trac_targeting, EXIT_MRK"saveRestoreAttrs"); + + return rc; +} + int hbrt_update_prep(void) { int rc = 0; + errlHndl_t pError = nullptr; + UtilLidMgr l_lidMgr(Util::TARGETING_BINARY_LIDID); + void *l_lidStructPtr = nullptr; + + bool l_usingRealLID = false; + + do + { + // Get size and location of attributes in reserved memory + uint64_t l_attr_size = 0; + uint64_t l_rsvdMem = hb_get_rt_rsvd_mem(Util::HBRT_MEM_LABEL_ATTR, + 0, l_attr_size); + + // Set pointer to reserved memory targeting data + void *l_rsvdMemPtr = reinterpret_cast<void*>(l_rsvdMem); + + // Create lidMgr and get size of Targeting Binary LID + size_t l_lidSize = 0; + pError = l_lidMgr.getLidSize(l_lidSize); + if(pError) + { + pError->collectTrace(TARG_COMP_NAME); + errlCommit(pError,TARG_COMP_ID); + + rc = 1; + + // break; @TODO RTC: 181285 uncomment + l_lidSize = l_attr_size; // @TODO RTC: 181285 remove + } + + if(!rc) // @TODO RTC: 181285 remove + { // @TODO RTC: 181285 remove + if(l_lidSize > l_attr_size) + { + TRACFCOMP( g_trac_targeting, + ERR_MRK"hbrt_update_prep: Sizes of targeting data, " + "LID Structure(New) 0x%0.8x is too large for Rsvd " + "Memory(Current) 0x%0.8x", + l_lidSize, + l_attr_size); + + rc = 1; + + break; + } + + // Get new structure from LID + pError = l_lidMgr.getStoredLidImage(l_lidStructPtr, l_lidSize); + if(pError) + { + pError->collectTrace(TARG_COMP_NAME); + errlCommit(pError,TARG_COMP_ID); + + rc = 1; + + // break; @TODO RTC: 181285 uncomment + } + } // @TODO RTC: 181285 remove + + if(rc) // @TODO RTC: 181285 remove if(rc){...}else{...} start + { + l_lidStructPtr = malloc(l_attr_size); + memcpy(l_lidStructPtr, + l_rsvdMemPtr, + l_attr_size); + + rc = 0; + } + else + { + l_usingRealLID = true; + } // @TODO RTC: 181285 remove if(rc){...}else{...} end + + // Validate LID Structure against Reserved Memory + rc = validateData(l_lidStructPtr, + l_rsvdMemPtr); + if(rc) + { + break; + } + + // Save/Restore attribute values from current Reserved Memory data into + // new LID Structure data + rc = saveRestoreAttrs(l_rsvdMemPtr, + l_lidStructPtr); + if(rc) + { + break; + } + + // Copy new LID Structure data over current Reserved Memory data + size_t l_copySize = std::min(l_lidSize, l_attr_size); + TRACFCOMP( g_trac_targeting, + "hbrt_update_prep: Copy 0x%0.8x bytes of targeting data", + l_copySize); + memcpy(l_rsvdMemPtr, + l_lidStructPtr, + l_copySize); + TRACFCOMP( g_trac_targeting, + "hbrt_update_prep: Set 0x%0.8x bytes to 0", + l_attr_size - l_copySize); + memset(reinterpret_cast<void*>( + reinterpret_cast<uint64_t>(l_rsvdMemPtr) + l_copySize), + 0, + l_attr_size - l_copySize); + } while(false); + + if(l_usingRealLID) // @TODO RTC: 181285 remove + { // @TODO RTC: 181285 remove + pError = l_lidMgr.releaseLidImage(); + if(pError) + { + pError->collectTrace(TARG_COMP_NAME); + errlCommit(pError,TARG_COMP_ID); + + rc = 1; + } + } // @TODO RTC: 181285 remove + else // @TODO RTC: 181285 remove + { // @TODO RTC: 181285 remove + free(l_lidStructPtr); // @TODO RTC: 181285 remove + l_lidStructPtr = nullptr; // @TODO RTC: 181285 remove + } // @TODO RTC: 181285 remove return rc; } |