From 467ae10a804451a843409e6b94a3c0108c083939 Mon Sep 17 00:00:00 2001 From: Nick Bofferding Date: Fri, 29 Mar 2013 00:01:56 -0500 Subject: Support generic PEER_TARGET navigation - Updated attribute compiler to lay down FSP specific PEER_TARGETS - Added common predicate to filter targets with specific value for attribute - Added generic PEER_TARGET navigation facility to filter utilities - Added support for platform specific attribute accessor specialization - Added target function to return target based on HUID Change-Id: I190087ee7fb24e80185bc955bd994ee14512a704 RTC: 41735 Reviewed-on: http://gfw160.austin.ibm.com:8080/gerrit/3796 Reviewed-by: Brian H. Horton Tested-by: Jenkins Server Reviewed-by: A. Patrick Williams III --- src/usr/targeting/common/target.C | 27 +++++ src/usr/targeting/common/utilFilter.C | 147 ++++++++++++++++++++++++++-- src/usr/targeting/common/xmltohb/xmltohb.pl | 85 +++++++++++++++- 3 files changed, 247 insertions(+), 12 deletions(-) (limited to 'src/usr/targeting/common') diff --git a/src/usr/targeting/common/target.C b/src/usr/targeting/common/target.C index 60134d156..6e92e53fc 100644 --- a/src/usr/targeting/common/target.C +++ b/src/usr/targeting/common/target.C @@ -41,6 +41,7 @@ #include #include #include +#include namespace TARGETING { @@ -310,6 +311,32 @@ uint8_t * Target::targetFFDC( uint32_t & o_size ) const #undef TARG_FN } +//****************************************************************************** +// Target::getTargetFromHuid() +//****************************************************************************** + +Target* Target::getTargetFromHuid( + const ATTR_HUID_type i_huid) const +{ + #define TARG_FN "getTargetFromHuid" + Target* l_pTarget = NULL; + + TARGETING::PredicateAttrVal huidMatches(i_huid); + + TARGETING::TargetRangeFilter targetsWithMatchingHuid( + TARGETING::targetService().begin(), + TARGETING::targetService().end(), + &huidMatches); + if(targetsWithMatchingHuid) + { + // Exactly one target will match the HUID, if any + l_pTarget = *targetsWithMatchingHuid; + } + + return l_pTarget; + #undef TARG_FN +} + #undef TARG_CLASS #undef TARG_NAMESPACE diff --git a/src/usr/targeting/common/utilFilter.C b/src/usr/targeting/common/utilFilter.C index 24e2fc620..d981b6051 100644 --- a/src/usr/targeting/common/utilFilter.C +++ b/src/usr/targeting/common/utilFilter.C @@ -30,6 +30,7 @@ #include #include #include +#include /** * Miscellaneous Filter Utility Functions @@ -179,24 +180,30 @@ void getAffinityTargets ( TARGETING::TargetHandleList& o_vector, } -void getChildAffinityTargets ( TARGETING::TargetHandleList& o_vector, - const Target * i_target, CLASS i_class, TYPE i_type, - bool i_functional ) +void getChildAffinityTargets( + TARGETING::TargetHandleList& o_vector, + const Target* i_target, + CLASS i_class, + TYPE i_type, + bool i_functional) { getAffinityTargets (o_vector, i_target, i_class, i_type, - TARGETING::TargetService::CHILD_BY_AFFINITY, - i_functional); + TARGETING::TargetService::CHILD_BY_AFFINITY, + i_functional); } -void getParentAffinityTargets ( TARGETING::TargetHandleList& o_vector, - const Target * i_target, CLASS i_class, TYPE i_type, - bool i_functional ) +void getParentAffinityTargets( + TARGETING::TargetHandleList& o_vector, + const Target* i_target, + CLASS i_class, + TYPE i_type, + bool i_functional ) { getAffinityTargets (o_vector, i_target, i_class, i_type, - TARGETING::TargetService::PARENT_BY_AFFINITY, - i_functional); + TARGETING::TargetService::PARENT_BY_AFFINITY, + i_functional); } const Target * getParentChip( const Target * i_pChiplet ) @@ -227,5 +234,125 @@ const Target * getParentChip( const Target * i_pChiplet ) return l_pChip; } +void getPeerTargets( + TARGETING::TargetHandleList& o_peerTargetList, + const Target* i_pSrcTarget, + const PredicateBase* i_pPeerFilter, + const PredicateBase* i_pResultFilter) +{ + #define TARG_FN "getPeerTargets" + TARG_ENTER(); + Target* l_pPeerTarget = NULL; + + if(i_pSrcTarget == NULL) + { + TARG_ASSERT("User tried to call getPeerTargets using NULL Target" + " Handle"); + } + + // Clear the list + o_peerTargetList.clear(); + do + { + // List to maintain all child targets which are found by get associated + // from the Src target with i_pPeerFilter predicate + TARGETING::TargetHandleList l_pSrcTarget_list; + + // Create input master predicate here by taking in the i_pPeerFilter + TARGETING::PredicatePostfixExpr l_superPredicate; + TARGETING::PredicateAttrVal + l_notNullPeerExist(NULL, true); + l_superPredicate.push(&l_notNullPeerExist); + if(i_pPeerFilter) + { + l_superPredicate.push(i_pPeerFilter).And(); + } + + // Check if the i_srcTarget is the leaf node + if(i_pSrcTarget->tryGetAttr(l_pPeerTarget)) + { + if(l_superPredicate(i_pSrcTarget)) + { + // Exactly one Peer Target to Cross + // Put this to input target list + l_pSrcTarget_list.push_back( + const_cast(i_pSrcTarget)); + } + else + { + TARG_INF("Input Target provided doesn't have a valid Peer " + "Target Attribute, Returning Empty List"); + break; + } + } + // Not a leaf node, find out all leaf node with valid PEER Target + else + { + (void) TARGETING::targetService().getAssociated( + l_pSrcTarget_list, + i_pSrcTarget, + TARGETING::TargetService::CHILD, + TARGETING::TargetService::ALL, + &l_superPredicate); + } + + // Now we have a list of input targets on which we have to find the peer + // Check if we have a result predicate filter to apply + if(i_pResultFilter == NULL) + { + // Simply get the Peer Target for all Src target in the list and + // return + for(TARGETING::TargetHandleList::const_iterator pTargetIt + = l_pSrcTarget_list.begin(); + pTargetIt != l_pSrcTarget_list.end(); + ++pTargetIt) + { + TARGETING::Target* l_pPeerTgt = + (*pTargetIt)->getAttr(); + o_peerTargetList.push_back(l_pPeerTgt); + } + break; + } + // Result predicate filter is not NULL, we need to apply this predicate + // on each of the PEER Target found on the input target list + else + { + for(TARGETING::TargetHandleList::const_iterator pTargetIt + = l_pSrcTarget_list.begin(); + pTargetIt != l_pSrcTarget_list.end(); + ++pTargetIt) + { + TARGETING::TargetHandleList l_peerTarget_list; + TARGETING::Target* l_pPeerTgt = + (*pTargetIt)->getAttr(); + + // Check whether this target matches the filter criteria + // or we have to look for ALL Parents matching the criteria. + if((*i_pResultFilter)(l_pPeerTgt)) + { + o_peerTargetList.push_back(l_pPeerTgt); + } + else + { + (void) TARGETING::targetService().getAssociated( + l_peerTarget_list, + l_pPeerTgt, + TARGETING::TargetService::PARENT, + TARGETING::TargetService::ALL, + i_pResultFilter); + if(!l_peerTarget_list.empty()) + { + // Insert the first one only. + o_peerTargetList.push_back( + l_peerTarget_list.front()); + } + } + } + } + } while(0); + + TARG_EXIT(); + #undef TARG_FN +} }; // end namespace diff --git a/src/usr/targeting/common/xmltohb/xmltohb.pl b/src/usr/targeting/common/xmltohb/xmltohb.pl index eb9a39625..89d7af58f 100755 --- a/src/usr/targeting/common/xmltohb/xmltohb.pl +++ b/src/usr/targeting/common/xmltohb/xmltohb.pl @@ -114,6 +114,7 @@ if($cfgVerbose) # Initialize some globals ################################################################################ +use constant INVALID_HUID=>0xffffffff; my $xml = new XML::Simple (KeyAttr=>[]); # Until full machine parseable workbook parsing splits out all the input files, @@ -135,7 +136,14 @@ validateAttributes($attributes); validateTargetInstances($attributes); validateTargetTypes($attributes); validateTargetTypesExtension($attributes); -handleTgtPtrAttributes(\$attributes, \%Target_t); +if($cfgIncludeFspAttributes) +{ + handleTgtPtrAttributesFsp(\$attributes, \%Target_t); +} +else +{ + handleTgtPtrAttributesHb(\$attributes, \%Target_t); +} # Open the output files and write them if( !($cfgSrcOutputDir =~ "none") ) @@ -426,11 +434,43 @@ sub validateTargetInstances{ } } +################################################################################ +# Convert Target_t PHYS_PATH into Peer target's HUID - FSP Specific +################################################################################ + +sub handleTgtPtrAttributesFsp +{ + my($attributes) = @_; + + # replace PEER_TARGET attribute value with PEER's HUID + foreach my $targetInstance (@{${$attributes}->{targetInstance}}) + { + foreach my $attr (@{$targetInstance->{attribute}}) + { + if (exists $attr->{default}) + { + if( ($attr->{default} ne "NULL") + && ($attr->{id} eq "PEER_TARGET")) + { + my $peerHUID = getPeerHuid(${$attributes}, + $attr->{default}); + if($peerHUID == INVALID_HUID) + { + fatal("HUID for Peer Target not found"); + } + $attr->{default} = (hex($peerHUID) << 32); + $attr->{default} = sprintf("0x%X",$attr->{default}); + } + } + } + } +} + ################################################################################ # Convert PHYS_PATH into index for Target_t attribute's value ################################################################################ -sub handleTgtPtrAttributes{ +sub handleTgtPtrAttributesHb{ my($attributes, $Target_t) = @_; my $aId = 0; @@ -482,6 +522,47 @@ sub handleTgtPtrAttributes{ } } +sub getPeerHuid +{ + my($attributes, $peerPhysPath) = @_; + + my $peerHUID = INVALID_HUID; + my $found = 0; + foreach my $targetInstance (@{$attributes->{targetInstance}}) + { + foreach my $attr (@{$targetInstance->{attribute}}) + { + if ($attr->{id} eq "PHYS_PATH") + { + if ($attr->{default} eq $peerPhysPath) + { + # $attr->{id} for HUID might have been lost in the iteration + # Need to repeat iteration + foreach my $attr1 (@{$targetInstance->{attribute}}) + { + if ($attr1->{id} eq "HUID") + { + $peerHUID = $attr1->{default}; + $found = 1; + last; + } + } + if($found) + { + last; + } + } + } + } + if($found) + { + last; + } + } + + return $peerHUID; +} + sub SOURCE_FILE_GENERATION_FUNCTIONS { } ################################################################################ -- cgit v1.2.1