diff options
Diffstat (limited to 'src/usr')
20 files changed, 1664 insertions, 383 deletions
diff --git a/src/usr/targeting/attrrp.C b/src/usr/targeting/attrrp.C index b5ae745ef..eaff4fd2b 100644 --- a/src/usr/targeting/attrrp.C +++ b/src/usr/targeting/attrrp.C @@ -73,7 +73,7 @@ namespace TARGETING Singleton<AttrRP>::instance().startup(io_taskRetErrl); } - void* AttrRP::getBaseAddress() + void* AttrRP::getBaseAddress(const NODE_ID i_nodeIdUnused) { return reinterpret_cast<void*>(VMM_VADDR_ATTR_RP); } @@ -568,10 +568,11 @@ namespace TARGETING } void AttrRP::readSectionData( - std::vector<TARGETING::sectionRefData>& o_pages, - const TARGETING::SECTION_TYPE i_sectionId) + std::vector<TARGETING::sectionRefData>& o_pages, + const TARGETING::SECTION_TYPE i_sectionId, + const NODE_ID i_nodeId) const { - sectionRefData sectionData = {0}; + sectionRefData sectionData; uint16_t count = 0; uint16_t pages = 0; diff --git a/src/usr/targeting/common/common.mk b/src/usr/targeting/common/common.mk index 509617f77..7a5cb8c27 100644 --- a/src/usr/targeting/common/common.mk +++ b/src/usr/targeting/common/common.mk @@ -41,6 +41,7 @@ PREDICATES_OBJS = \ ITERATORS_OBJS = \ targetiterator.o \ + rawtargetiterator.o \ rangefilter.o TARGET_OBJS = \ diff --git a/src/usr/targeting/common/genHwsvMrwXml.pl b/src/usr/targeting/common/genHwsvMrwXml.pl index c54368838..349b73054 100755 --- a/src/usr/targeting/common/genHwsvMrwXml.pl +++ b/src/usr/targeting/common/genHwsvMrwXml.pl @@ -865,6 +865,9 @@ my $Mproc = 0; my $fru_id = 0; my @fru_paths; my $hasProc = 0; +my $hash_ax_buses; +my $axBusesHuidInit = 0; + for (my $curnode = 0; $curnode <= $MAXNODE; $curnode++) { @@ -907,6 +910,32 @@ if ($hasProc == 0) next; } +#preCalculate HUID for A-Bus +if($axBusesHuidInit == 0) +{ + $axBusesHuidInit = 1; + for (my $my_curnode = 0; $my_curnode <= $MAXNODE; $my_curnode++) + { + for (my $do_core = 0, my $i = 0; $i <= $#STargets; $i++) + { + if ($STargets[$i][NODE_FIELD] != $my_curnode) + { + next; + } + if ($STargets[$i][NAME_FIELD] eq "mcs") + { + my $proc = $STargets[$i][POS_FIELD]; + if (($STargets[$i+1][NAME_FIELD] eq "pu") || + ($STargets[$i+1][NAME_FIELD] eq "memb")) + { + preCalculateAxBusesHUIDs($my_curnode, $proc, "A"); + preCalculateAxBusesHUIDs($my_curnode, $proc, "X"); + } + } + } + } +} + # Fourth, generate the proc, occ, ex-chiplet, mcs-chiplet # unit-tp (if on fsp), pcie bus and A/X-bus. my $ex_count = 0; @@ -916,6 +945,7 @@ my $proc_ordinal_id =0; #my $fru_id = 0; #my @fru_paths; my $hwTopology =0; + for (my $do_core = 0, my $i = 0; $i <= $#STargets; $i++) { if ($STargets[$i][NODE_FIELD] != $node) @@ -1194,6 +1224,30 @@ exit 0; ########## Subroutines ############## ################################################################################ +# utility function used to preCalculate the AX Buses HUIDs +################################################################################ + +sub preCalculateAxBusesHUIDs +{ + my ($my_node, $proc, $type) = @_; + + my ($minbus, $maxbus, $numperchip, $typenum, $type) = + getBusInfo($type, $CHIPNAME); + + for my $i ( $minbus .. $maxbus ) + { + my $uidstr = sprintf( "0x%02X%02X%04X", + ${my_node}, + $typenum, + $i+$proc*($numperchip)+${my_node}*8*($numperchip)); + my $phys_path = + "physical:sys-$sys/node-$my_node/proc-$proc/${type}bus-$i"; + $hash_ax_buses->{$phys_path} = $uidstr; + #print STDOUT "Phys Path = $phys_path, HUID = $uidstr\n"; + } +} + +################################################################################ # utility function used to call plugins. if none exists, call is skipped. ################################################################################ @@ -1850,9 +1904,20 @@ sub generate_proc <default>$dcm_installed</default> </attribute>"; + if ($master) + { + print " + <!-- Master Proc attribute --> + <attribute> + <id>PROC_MASTER_TYPE</id> + <default>ACTING_MASTER</default> + </attribute>"; + + } if ($slave) { print " + <!-- Slave Proc attribute --> <!-- FSI is connected via node${node}:proc${Mproc}:MFSI-$fsi --> <attribute> <id>FSI_MASTER_CHIP</id> @@ -2221,23 +2286,31 @@ sub generate_a_pcie "; } +sub getBusInfo +{ + my($type, $chipName) = @_; + + my $minbus = ($type eq "A") ? 0 : ($chipName eq "murano") ? 1 : 0; + my $maxbus = ($type eq "A") ? 2 : ($chipName eq "murano") ? 1 : 3; + my $numperchip = ($type eq "A") ? 3 : 4; + my $typenum = ($type eq "A") ? 0x0F : 0x0E; + $type = lc( $type ); + + return ($minbus, $maxbus, $numperchip, $typenum, $type); +} + sub generate_ax_buses { my ($proc, $type, $ordinalId) = @_; my $proc_name = "n${node}p${proc}"; print "\n<!-- $SYSNAME $proc_name ${type}BUS units -->\n"; - my $minbus = ($type eq "A") ? 0 : ($CHIPNAME eq "murano") ? 1 : 0; - my $maxbus = ($type eq "A") ? 2 : ($CHIPNAME eq "murano") ? 1 : 3; - my $numperchip = ($type eq "A") ? 3 : 4; - my $typenum = ($type eq "A") ? 0x0F : 0x0E; - $type = lc( $type ); + + my ($minbus, $maxbus, $numperchip, $typenum, $type) = + getBusInfo($type, $CHIPNAME); + for my $i ( $minbus .. $maxbus ) { - my $uidstr = sprintf( "0x%02X%02X%04X", - ${node}, - $typenum, - $i+$proc*($numperchip)+${node}*8*($numperchip)); my $c_ordinalId = $i+($ordinalId*($numperchip)); my $peer = 0; @@ -2279,14 +2352,19 @@ sub generate_ax_buses last; } } + my $phys_path = + "physical:sys-${sys}/node-${node}/proc-${proc}/${type}bus-${i}"; print " <targetInstance> <id>sys${sys}node${node}proc${proc}${type}bus$i</id> <type>unit-${type}bus-$CHIPNAME</type> - <attribute><id>HUID</id><default>${uidstr}</default></attribute> + <attribute> + <id>HUID</id> + <default>$hash_ax_buses->{$phys_path}</default> + </attribute> <attribute> <id>PHYS_PATH</id> - <default>physical:sys-$sys/node-$node/proc-$proc/${type}bus-$i</default> + <default>$phys_path</default> </attribute> <attribute> <id>AFFINITY_PATH</id> @@ -2302,12 +2380,17 @@ sub generate_ax_buses </attribute>"; if ($peer) { + my $peerPhysPath = "physical:sys-${sys}/node-${p_node}/" + ."proc-${p_proc}/${type}bus-${p_port}"; print " <attribute> <id>PEER_TARGET</id> - <default>physical:sys-$sys/node-$p_node/proc-$p_proc/" - . "${type}bus-$p_port</default> - </attribute>"; + <default>$peerPhysPath</default> + </attribute> + <compileAttribute> + <id>PEER_HUID</id> + <default>$hash_ax_buses->{$peerPhysPath}</default> + </compileAttribute>"; if ($type eq "a") { print " diff --git a/src/usr/targeting/common/genNodeMrwXml.pl b/src/usr/targeting/common/genNodeMrwXml.pl index 8c686b05c..930c8670b 100755 --- a/src/usr/targeting/common/genNodeMrwXml.pl +++ b/src/usr/targeting/common/genNodeMrwXml.pl @@ -154,118 +154,13 @@ foreach my $targetInstance (@{$sysInfo->{targetInstance}}) my $nodeValue = $targetId; $nodeValue =~ s/.*node(\d?).*/$1/; - #TODO: revisit when doing multi-node - #for now the in a multi-node/drawer system the abus goes outside - #the node/drawer boundry. So will remove the peer nodes since there - #in no current method of reaching the peer if ($nodeValue < $#nodeFD ) { - if ($targetId =~ m/abus/) - { - #make the peer target null - my $count =0; - foreach my $attrValue (@{$targetInstance->{'attribute'}}) - { - if ($attrValue->{'id'}[0] eq "PEER_TARGET") - { - splice @{$targetInstance->{'attribute'}},$count,1; - last; - } - $count++; - - } - my $xmlDataNoPeer= XMLout($targetInstance,RootName => "targetInstance"); - #print Dumper($xmlDataNoPeer); - print {$nodeFD[$nodeValue]} $xmlDataNoPeer; - } - elsif ($targetId =~ m/psi/) - { - #TODO: revisit when doing multi-node - #if the psi link is going to node 0 or belongs to node 0 keep - #else set to default. - - my $count =0; - my $nodePeer =-1; - my $spliceLoc =0; - foreach my $attrValue (@{$targetInstance->{'attribute'}}) - { - if($attrValue->{'id'}[0] eq "PEER_TARGET") - { - $nodePeer = $attrValue->{'default'}[0]; - $nodePeer =~ s/.*node-(\d?).*/$1/; - if ($nodePeer == 4) - { - $nodePeer =0; - } - last; - } - - $count++; - } - - if ($nodePeer == $nodeValue ) - { - #in this case the target and peer are pointing to same node - #print Dumper($xmlData); - print {$nodeFD[$nodeValue]} $xmlData; - } - else - { - #the target or the peer is pointing off the node - #so need to remove the peer target - splice @{$targetInstance->{'attribute'}},$count,1; - my $xmlDataNoPeer= XMLout($targetInstance,RootName => "targetInstance"); - #print Dumper($xmlDataNoPeer); - print {$nodeFD[$nodeValue]} $xmlDataNoPeer; - } - } - else - { - print {$nodeFD[$nodeValue]} $xmlData; - } - + print {$nodeFD[$nodeValue]} $xmlData; } elsif ($nodeValue == $#nodeFD) { - #TODO: revisit when doing multi-node - #there should not be node 4 targeting data for node 4 - #because node 4 is a FSP(maxdale) not a node. However - #do need to include node 4 psi info for node 0 - - my $psiValue = $targetId; - #print("psiValue from targ = ",$psiValue,"\n"); - if ($targetId=~ m/psi/) - { - my $count =0; - foreach my $attrValue (@{$targetInstance->{'attribute'}}) - { - if($attrValue->{'id'}[0] eq "PEER_TARGET") - { - if ($attrValue->{'default'}[0] =~ m/node-0/) - { - #print Dumper($xmlData); - #all node-4 targets go into the node 0 targeting binary - print {$nodeFD[0]} $xmlData; - } - else - { - #if not going to node 4 then need to remove the peer target - splice @{$targetInstance->{'attribute'}},$count,1; - my $xmlDataNoPeer= XMLout($targetInstance,RootName => "targetInstance"); - #print Dumper($xmlDataNoPeer); - print {$nodeFD[0]} $xmlDataNoPeer; - } - last; - } - $count++; - } - } - else - { - #this is node 4 information that does not contain psi information - print {$nodeFD[0]} $xmlData; - } - + print {$nodeFD[0]} $xmlData; } else { diff --git a/src/usr/targeting/common/iterators/rangefilter.C b/src/usr/targeting/common/iterators/rangefilter.C index 7e3ddf333..961db1ea7 100644 --- a/src/usr/targeting/common/iterators/rangefilter.C +++ b/src/usr/targeting/common/iterators/rangefilter.C @@ -1,30 +1,30 @@ -// IBM_PROLOG_BEGIN_TAG -// This is an automatically generated prolog. -// -// $Source: src/usr/targeting/iterators/rangefilter.C $ -// -// 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/usr/targeting/common/iterators/rangefilter.C $ */ +/* */ +/* IBM CONFIDENTIAL */ +/* */ +/* COPYRIGHT International Business Machines Corp. 2011,2013 */ +/* */ +/* p1 */ +/* */ +/* Object Code Only (OCO) source materials */ +/* Licensed Internal Code Source Materials */ +/* IBM HostBoot Licensed Internal Code */ +/* */ +/* The source code for this program is not published or otherwise */ +/* divested of its trade secrets, irrespective of what has been */ +/* deposited with the U.S. Copyright Office. */ +/* */ +/* Origin: 30 */ +/* */ +/* IBM_PROLOG_END_TAG */ /** * @file common/targeting/iterators/rangefilter.C * - * @brief Implementation of an object which takes an iterator range and + * @brief Implementation of an object which takes an iterator range and * allows caller to iterate through the elements which match a supplied * predicate (filter) */ @@ -39,6 +39,7 @@ // Targeting Component #include <targeting/common/iterators/iterators.H> +#include <targeting/common/trace.H> //****************************************************************************** // Macros @@ -66,17 +67,21 @@ namespace TARGETING template<typename IteratorType> void RangeFilter<IteratorType>::advance() { + #define TARG_FN "RangeFilter<IteratorType>::advance()" + if(iv_current != iv_end) { while( (++iv_current) != iv_end ) { - if( (!iv_pPredicate) + if( (!iv_pPredicate) || ((*iv_pPredicate)(*iv_current))) { break; } } } + + #undef TARG_FN } //****************************************************************************** @@ -100,8 +105,8 @@ void RangeFilter<IteratorType>::advanceIfNoMatch() template<typename IteratorType> RangeFilter<IteratorType>::operator fake_bool() const -{ - return (iv_current != iv_end) +{ + return (iv_current != iv_end) ? &RangeFilter::notComparable : NULL; } @@ -115,7 +120,7 @@ template void RangeFilter<ConstTargetIterator>::advance(); template void RangeFilter<TargetIterator>::advanceIfNoMatch(); template void RangeFilter<ConstTargetIterator>::advanceIfNoMatch(); -template RangeFilter<TargetIterator>::operator fake_bool() const; +template RangeFilter<TargetIterator>::operator fake_bool() const; template RangeFilter<ConstTargetIterator>::operator fake_bool() const; #undef TARG_CLASS diff --git a/src/usr/targeting/common/iterators/rawtargetiterator.C b/src/usr/targeting/common/iterators/rawtargetiterator.C new file mode 100644 index 000000000..9946a3d0f --- /dev/null +++ b/src/usr/targeting/common/iterators/rawtargetiterator.C @@ -0,0 +1,91 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/usr/targeting/common/iterators/rawtargetiterator.C $ */ +/* */ +/* IBM CONFIDENTIAL */ +/* */ +/* COPYRIGHT International Business Machines Corp. 2013 */ +/* */ +/* p1 */ +/* */ +/* Object Code Only (OCO) source materials */ +/* Licensed Internal Code Source Materials */ +/* IBM HostBoot Licensed Internal Code */ +/* */ +/* The source code for this program is not published or otherwise */ +/* divested of its trade secrets, irrespective of what has been */ +/* deposited with the U.S. Copyright Office. */ +/* */ +/* Origin: 30 */ +/* */ +/* IBM_PROLOG_END_TAG */ + +/** + * @file targeting/common/iterators/rawtargetiterator.C + * + * @brief Implementation of raw iterator/const raw iterator used to iterate + * through all target service targets + */ + +//****************************************************************************** +// Includes +//****************************************************************************** + +// STD + +// Other Host Boot Components + +// Targeting Component +#include <targeting/common/iterators/iterators.H> +#include <targeting/common/targetservice.H> + +//****************************************************************************** +// Macros +//****************************************************************************** + +#undef TARG_NAMESPACE +#undef TARG_CLASS +#undef TARG_FUNC + +//****************************************************************************** +// Implementation +//****************************************************************************** + +namespace TARGETING +{ + +#define TARG_NAMESPACE "TARGETING::" + +#define TARG_CLASS "_TargetRawIterator<T>::" + +//****************************************************************************** +// TargetIterator::advance +//****************************************************************************** + +template<typename T> +void _TargetRawIterator<T>::advance() +{ + static TargetService& l_targetService = targetService(); + + // If cursor points to end()/NULL, do nothing. Otherwise, check to see if + // it should advance (possibly to NULL) + if(iv_pCurrent != NULL) + { + iv_pCurrent = l_targetService.getNextTarget(iv_pCurrent); + } +} + +//****************************************************************************** +// Explicit template class member function instantiations +//****************************************************************************** + +template void _TargetRawIterator<Target*>::advance(); +template void _TargetRawIterator<const Target*>::advance(); + +#undef TARG_CLASS + +#undef TARG_NAMESPACE + +} // End namespace TARGETING + diff --git a/src/usr/targeting/common/iterators/targetiterator.C b/src/usr/targeting/common/iterators/targetiterator.C index 76b687641..ff73641ea 100644 --- a/src/usr/targeting/common/iterators/targetiterator.C +++ b/src/usr/targeting/common/iterators/targetiterator.C @@ -1,31 +1,31 @@ -// IBM_PROLOG_BEGIN_TAG -// This is an automatically generated prolog. -// -// $Source: src/usr/targeting/iterators/targetiterator.C $ -// -// 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/usr/targeting/common/iterators/targetiterator.C $ */ +/* */ +/* IBM CONFIDENTIAL */ +/* */ +/* COPYRIGHT International Business Machines Corp. 2011,2013 */ +/* */ +/* p1 */ +/* */ +/* Object Code Only (OCO) source materials */ +/* Licensed Internal Code Source Materials */ +/* IBM HostBoot Licensed Internal Code */ +/* */ +/* The source code for this program is not published or otherwise */ +/* divested of its trade secrets, irrespective of what has been */ +/* deposited with the U.S. Copyright Office. */ +/* */ +/* Origin: 30 */ +/* */ +/* IBM_PROLOG_END_TAG */ /** * @file targeting/common/iterators/targetiterator.C * * @brief Implementation of iterator/const iterator used to iterate through - * target service targets + * target service targets */ //****************************************************************************** @@ -66,30 +66,55 @@ namespace TARGETING template<typename T> void _TargetIterator<T>::advance() { - TargetService& l_targetService = targetService(); + static TargetService& l_targetService = targetService(); - // If cursor points to end()/NULL, do nothing. Otherwise, check to see if + // If cursor points to end()/NULL, do nothing. Otherwise, check to see if // it should advance (possibly to NULL) - if(iv_pCurrent != NULL) + if(likely (iv_pCurrent != NULL) ) { - // Advance to end() if no targets available. Otherwise, check to see if - // it should advance (possibly to NULL) - if (l_targetService.iv_maxTargets > 0) + // In HB the first block will always compile to run and take the optimal + // iterator performance path that assumes only one node's worth of data + if(!PLAT::PROPERTIES::MULTINODE_AWARE) { - // If at or past last element, advance to end() else advance - if(iv_pCurrent >= - &(*l_targetService.iv_targets)[l_targetService.iv_maxTargets-1]) + if ( likely( (!l_targetService.iv_nodeInfo.empty()) ) + && likely( (l_targetService.iv_nodeInfo[0].maxTargets > 0) ) ) { - iv_pCurrent = NULL; + // If at or past last element, advance to end() else advance + if(unlikely ( + iv_pCurrent >= + &(*(l_targetService.iv_nodeInfo[0]).targets) + [l_targetService.iv_nodeInfo[0].maxTargets-1] + )) + { + iv_pCurrent = NULL; + } + else + { + iv_pCurrent++; + } } else { - iv_pCurrent++; + iv_pCurrent = NULL; } + } else { - iv_pCurrent = NULL; + iv_pCurrent = l_targetService.getNextTarget(iv_pCurrent); + if(likely(iv_pCurrent != NULL)) + { + // Targeting XML and compiler ensure that there are no back to + // back hidden system targets; therefore, if the current one is + // a hidden system target, skip it and the next one will either + // be valid or NULL (i.e. end()) + if(unlikely( + l_targetService.isNonMasterNodeSystemTarget(iv_pCurrent))) + { + iv_pCurrent = l_targetService.getNextTarget(iv_pCurrent); + } + } + } } } diff --git a/src/usr/targeting/common/target.C b/src/usr/targeting/common/target.C index 5209c3891..6d619a7ab 100644 --- a/src/usr/targeting/common/target.C +++ b/src/usr/targeting/common/target.C @@ -219,9 +219,11 @@ void Target::_getAttrPtr( if(TARG_ADDR_TRANSLATION_REQUIRED) { pAttrId = static_cast<ATTRIBUTE_ID*>( - TARG_GET_SINGLETON(TARGETING::theAttrRP).translateAddr(pAttrId)); + TARG_GET_SINGLETON(TARGETING::theAttrRP).translateAddr(pAttrId, + static_cast<const Target*>(this))); ppAttrAddr = static_cast<AbstractPointer<void>*>( - TARG_GET_SINGLETON(TARGETING::theAttrRP).translateAddr(ppAttrAddr)); + TARG_GET_SINGLETON(TARGETING::theAttrRP).translateAddr(ppAttrAddr, + static_cast<const Target*>(this))); } if ((pAttrId != NULL) && (ppAttrAddr != NULL)) @@ -245,7 +247,7 @@ void Target::_getAttrPtr( { l_pAttr = TARG_GET_SINGLETON(TARGETING::theAttrRP).translateAddr( - l_pAttr); + l_pAttr, static_cast<const Target*>(this)); } } } diff --git a/src/usr/targeting/common/targetservice.C b/src/usr/targeting/common/targetservice.C index ce2c3906c..f434765fd 100644 --- a/src/usr/targeting/common/targetservice.C +++ b/src/usr/targeting/common/targetservice.C @@ -36,6 +36,7 @@ #include <stdio.h> #include <stdlib.h> #include <string.h> +#include <map> // This component #include <targeting/common/targetservice.H> @@ -44,6 +45,11 @@ #include <targeting/attrrp.H> #include <targeting/common/trace.H> #include <targeting/adapters/types.H> +#include <targeting/targplatutil.H> +#include <targeting/targplatreasoncodes.H> +#include <attributetraits.H> + +#undef EXTRA_SANITY_CHECKING //****************************************************************************** // targetService @@ -56,6 +62,9 @@ namespace TARGETING #define TARG_CLASS "targetService" +// It is defined here to limit the scope +#define MAX_NODE_ID iv_nodeInfo.size() + //****************************************************************************** // targetService //****************************************************************************** @@ -88,7 +97,7 @@ TRAC_INIT(&g_trac_targeting, "TARG", 4096); //****************************************************************************** TargetService::TargetService() : - iv_initialized(false), iv_maxTargets(0), iv_pPnor(NULL) + iv_initialized(false) { #define TARG_FN "TargetService()" @@ -112,43 +121,76 @@ TargetService::~TargetService() // TargetService::init //****************************************************************************** -void TargetService::init() +void TargetService::init(const size_t i_maxNodes) { #define TARG_FN "init()" TARG_ENTER(); - // Build the association mappings - AssociationAttrMap a1 = {PARENT, INWARDS, ATTR_PHYS_PATH}; - AssociationAttrMap a2 = {CHILD, OUTWARDS, ATTR_PHYS_PATH}; - AssociationAttrMap a3 = {PARENT_BY_AFFINITY, INWARDS, ATTR_AFFINITY_PATH}; - AssociationAttrMap a4 = {CHILD_BY_AFFINITY, OUTWARDS, ATTR_AFFINITY_PATH}; - AssociationAttrMap a5 = {VOLTAGE_SUPPLIER, INWARDS, ATTR_POWER_PATH}; - AssociationAttrMap a6 = {VOLTAGE_CONSUMER, OUTWARDS, ATTR_POWER_PATH}; - iv_associationMappings.push_back(a1); - iv_associationMappings.push_back(a2); - iv_associationMappings.push_back(a3); - iv_associationMappings.push_back(a4); - iv_associationMappings.push_back(a5); - iv_associationMappings.push_back(a6); - - // Cache location of RO section containing all the attribute metadata - TargetingHeader* l_pHdr = reinterpret_cast<TargetingHeader*>( - TARG_GET_SINGLETON(TARGETING::theAttrRP).getBaseAddress()); - - TARG_ASSERT((l_pHdr != NULL), TARG_ERR_LOC - "FATAL: Targeting header is NULL!") - TARG_ASSERT((l_pHdr->eyeCatcher == PNOR_TARG_EYE_CATCHER), TARG_ERR_LOC - "FATAL: Targeting eyecatcher not found; " - "expected 0x%08X but got 0x%08X", - PNOR_TARG_EYE_CATCHER,l_pHdr->eyeCatcher); - - iv_pPnor = reinterpret_cast<uint32_t*>( - (reinterpret_cast<char*>(l_pHdr) + l_pHdr->headerSize)); - - (void)_configureTargetPool(); - - iv_initialized = true; + if(!iv_initialized) + { + TARG_INF("Max Nodes to initialize is [%d]", i_maxNodes); + + // Build the association mappings + AssociationAttrMap a1 = {PARENT, INWARDS, ATTR_PHYS_PATH}; + AssociationAttrMap a2 = {CHILD, OUTWARDS, ATTR_PHYS_PATH}; + AssociationAttrMap a3 = {PARENT_BY_AFFINITY, + INWARDS,ATTR_AFFINITY_PATH}; + AssociationAttrMap a4 = {CHILD_BY_AFFINITY, + OUTWARDS,ATTR_AFFINITY_PATH}; + AssociationAttrMap a5 = {VOLTAGE_SUPPLIER, INWARDS, ATTR_POWER_PATH}; + AssociationAttrMap a6 = {VOLTAGE_CONSUMER, OUTWARDS, ATTR_POWER_PATH}; + iv_associationMappings.push_back(a1); + iv_associationMappings.push_back(a2); + iv_associationMappings.push_back(a3); + iv_associationMappings.push_back(a4); + iv_associationMappings.push_back(a5); + iv_associationMappings.push_back(a6); + + for(uint8_t l_nodeCnt=0; l_nodeCnt<i_maxNodes; l_nodeCnt++) + { + NodeSpecificInfo l_nodeInfo; + l_nodeInfo.nodeId = static_cast<NODE_ID>(l_nodeCnt); + + // Cache location of RO section containing all the attribute + // metadata + TargetingHeader* l_pHdr = reinterpret_cast<TargetingHeader*>( + TARG_GET_SINGLETON(TARGETING::theAttrRP).getBaseAddress( + static_cast<NODE_ID>(l_nodeCnt))); + + if(NULL == l_pHdr) + { + TARG_INF("Targeting header is NULL for Node Id [%d]", + l_nodeCnt); + TARG_ASSERT(0, TARG_ERR_LOC + "Targeting Header for Node [%d] cannot be NULL", l_nodeCnt); + } + else + { + TARG_ASSERT((l_pHdr->eyeCatcher == PNOR_TARG_EYE_CATCHER), + TARG_ERR_LOC "FATAL: Targeting eyecatcher not found; " + "expected 0x%08X but got 0x%08X", + PNOR_TARG_EYE_CATCHER,l_pHdr->eyeCatcher); + + l_nodeInfo.pPnor = reinterpret_cast<uint32_t*>( + (reinterpret_cast<char*>(l_pHdr) + l_pHdr->headerSize)); + + (void)_configureTargetPool(l_nodeInfo); + + l_nodeInfo.initialized = true; + } + iv_nodeInfo.push_back(l_nodeInfo); + } + + bool masterNodeCapable = false; + (void)UTIL::subsystemIsMasterNodeCapable(masterNodeCapable); + if(masterNodeCapable) + { + (void)initDefaultMasterNode(); + } + + iv_initialized = true; + } TARG_EXIT(); @@ -156,26 +198,74 @@ void TargetService::init() } //****************************************************************************** +// TargetService:: _getFirstTargetForIterators +//****************************************************************************** + +void TargetService::_getFirstTargetForIterators(Target*& o_firstTargetPtr) const +{ + #define TARG_FN "_getFirstTargetForIterators()" + TARG_ASSERT(iv_initialized, TARG_ERR_LOC + "USAGE: TargetService not initialized"); + + for(uint8_t l_nodeCnt=0; l_nodeCnt<MAX_NODE_ID; ++l_nodeCnt) + { + /* This will come inside for initialized node only.. Just for safety we + * are checking for maxTargets & whether it is initialized or not */ + if((iv_nodeInfo[l_nodeCnt].initialized == true) && + (iv_nodeInfo[l_nodeCnt].maxTargets > 0)) + { + /* Assumption - + * Here we are assuming that the first target of any binary is not + * the system target, to make sure this ithe binary compiler needs + * to compile the binary in this specific order. + */ + o_firstTargetPtr = &(*(iv_nodeInfo[l_nodeCnt].targets))[0]; + + TARG_ASSERT(o_firstTargetPtr != NULL, TARG_ERR_LOC + "FATAL: Could not find any targets"); + break; + } + } + #undef TARG_FN +} + +//****************************************************************************** // TargetService::begin (non-const version) //****************************************************************************** TargetService::iterator TargetService::begin() { #define TARG_FN "begin()" + Target* l_pFirstTarget = NULL; TARG_ASSERT(iv_initialized, TARG_ERR_LOC "USAGE: TargetService not initialized"); - Target* l_pFirstTarget = (iv_maxTargets == 0) ? NULL : &(*iv_targets)[0]; - TARG_ASSERT(l_pFirstTarget != NULL, TARG_ERR_LOC - "FATAL: Could not find any targets"); - + _getFirstTargetForIterators(l_pFirstTarget); return iterator(l_pFirstTarget); #undef TARG_FN } //****************************************************************************** +// TargetService::raw_begin (non-const version) +//****************************************************************************** + +TargetService::rawiterator TargetService::raw_begin() +{ + #define TARG_FN "raw_begin()" + Target* l_pFirstTarget = NULL; + + TARG_ASSERT(iv_initialized, TARG_ERR_LOC + "USAGE: TargetService not initialized"); + + _getFirstTargetForIterators(l_pFirstTarget); + return rawiterator(l_pFirstTarget); + + #undef TARG_FN +} + +//****************************************************************************** // TargetService::begin (const version) //****************************************************************************** @@ -183,20 +273,40 @@ TargetService::iterator TargetService::begin() _TargetIterator<const Target*> TargetService::begin() const { #define TARG_FN "begin() const" + Target* l_pTmpFirstTarget = NULL; TARG_ASSERT(iv_initialized, TARG_ERR_LOC "USAGE: TargetService not initialized"); - const Target* l_pFirstTarget = - (iv_maxTargets == 0) ? NULL : &(*iv_targets)[0]; - TARG_ASSERT(l_pFirstTarget != NULL, TARG_ERR_LOC - "FATAL: Could not find any targets"); + _getFirstTargetForIterators(l_pTmpFirstTarget); + const Target* l_pFirstTarget = l_pTmpFirstTarget; return const_iterator(l_pFirstTarget); #undef TARG_FN } + +//****************************************************************************** +// TargetService::raw_begin (const version) +//****************************************************************************** + +_TargetRawIterator<const Target*> TargetService::raw_begin() const +{ + #define TARG_FN "raw_begin() const" + Target* l_pTmpFirstTarget = NULL; + + TARG_ASSERT(iv_initialized, TARG_ERR_LOC + "USAGE: TargetService not initialized"); + + _getFirstTargetForIterators(l_pTmpFirstTarget); + const Target* l_pFirstTarget = l_pTmpFirstTarget; + + return const_rawiterator(l_pFirstTarget); + + #undef TARG_FN +} + //****************************************************************************** // TargetService::end (non-const version) //****************************************************************************** @@ -214,6 +324,22 @@ TargetService::iterator TargetService::end() } //****************************************************************************** +// TargetService::raw_end (non-const version) +//****************************************************************************** + +TargetService::rawiterator TargetService::raw_end() +{ + #define TARG_FN "raw_end()" + + TARG_ASSERT(iv_initialized, TARG_ERR_LOC + "USAGE: TargetService not initialized"); + + return rawiterator(NULL); + + #undef TARG_FN +} + +//****************************************************************************** // TargetService::end (const version) //****************************************************************************** @@ -230,6 +356,108 @@ TargetService::const_iterator TargetService::end() const } //****************************************************************************** +// TargetService::raw_end (const version) +//****************************************************************************** + +TargetService::const_rawiterator TargetService::raw_end() const +{ + #define TARG_FN "raw_end() const" + + TARG_ASSERT(iv_initialized, TARG_ERR_LOC + "USAGE: TargetService not initialized"); + + return const_rawiterator(NULL); + + #undef TARG_FN +} + +//****************************************************************************** +// TargetService::getNextInitializedNode +//****************************************************************************** + +uint8_t TargetService::getNextInitializedNode(const NODE_ID i_node) const +{ + #define TARG_FN "getNextInitializedNode(...)" + uint8_t l_nodeCnt = 0; + bool l_foundNode = false; + + if(static_cast<uint32_t>(i_node + 1) < MAX_NODE_ID) + { + for(l_nodeCnt=(i_node +1); l_nodeCnt<MAX_NODE_ID; ++l_nodeCnt) + { + if((iv_nodeInfo[l_nodeCnt].initialized) && + (iv_nodeInfo[l_nodeCnt].maxTargets > 0)) + { + l_foundNode = true; + break; + } + } + } + if(l_foundNode == false) + { + // Assign Invalid node + l_nodeCnt = MAX_NODE_ID; + } + return l_nodeCnt; + #undef TARG_FN +} + +//****************************************************************************** +// TargetService::getNextTarget +//****************************************************************************** + +Target* TargetService::getNextTarget(const Target* i_pTarget) const +{ + #define TARG_FN "getNextTarget(...)" + Target* l_pTarget = const_cast<Target*>(i_pTarget); + bool l_targetFound = false; + if(l_pTarget != NULL) + { + for(uint8_t i_node=0; i_node<MAX_NODE_ID; ++i_node) + { + if((iv_nodeInfo[i_node].initialized) && + (iv_nodeInfo[i_node].maxTargets > 0) && + ((l_pTarget >= &(*(iv_nodeInfo[i_node]).targets)[0]) && + (l_pTarget <= &(*(iv_nodeInfo[i_node]).targets)[ + iv_nodeInfo[i_node].maxTargets - 1]))) + { + if( l_pTarget == &(*(iv_nodeInfo[i_node]).targets)[iv_nodeInfo[ + i_node].maxTargets - 1] ) + { + // Go for next node + uint8_t l_nextNode = getNextInitializedNode( + static_cast<NODE_ID>(i_node)); + if(l_nextNode != MAX_NODE_ID) + { + l_pTarget = &(*(iv_nodeInfo[l_nextNode].targets))[0]; + l_targetFound = true; + break; + } + else + { + l_targetFound = false; + break; + } + } + else + { + ++l_pTarget; + l_targetFound = true; + break; + } + } + } + } + if(l_targetFound == false) + { + l_pTarget = NULL; + } + + return l_pTarget; + #undef TARG_FN +} + +//****************************************************************************** // TargetService::getTopLevelTarget //****************************************************************************** @@ -258,21 +486,32 @@ void TargetService::exists( { #define TARG_FN "exists(...)" - bool l_found = false; + o_exists = false; TARG_ASSERT(iv_initialized, TARG_ERR_LOC "USAGE: TargetService not initialized"); - for (uint32_t i = 0; i < iv_maxTargets; ++i) + PredicateAttrVal<TARGETING::ATTR_PHYS_PATH> l_entityPathMatches( + i_entityPath); + + TARGETING::TargetRangeFilter l_targetsWithMatchingEntityPath( + TARGETING::targetService().begin(), + TARGETING::targetService().end(), + &l_entityPathMatches); + + if(l_targetsWithMatchingEntityPath) { - if (i_entityPath == (*iv_targets)[i].getAttr<ATTR_PHYS_PATH> ()) + o_exists = true; + + #ifdef EXTRA_SANITY_CHECKING + ++l_targetsWithMatchingEntityPath; + if(l_targetsWithMatchingEntityPath) { - l_found = true; + TARG_ASSERT(0, TARG_ERR_LOC "Should have found a single match"); } + #endif } - o_exists = l_found; - #undef TARG_FN } @@ -285,36 +524,68 @@ Target* TargetService::toTarget( { #define TARG_FN "toTarget(...)" - // Used by -> operator on EntityPath for convenience (can be dangerous - // though!) Target* l_pTarget = NULL; TARG_ASSERT(iv_initialized, TARG_ERR_LOC - "USAGE: TargetService not initialized"); + "USAGE: TargetService not initialized"); - for (uint32_t i = 0; i < iv_maxTargets; ++i) + if(i_entityPath.type() == EntityPath::PATH_PHYSICAL) { - bool found = false; - switch(i_entityPath.type()) + PredicateAttrVal<TARGETING::ATTR_PHYS_PATH> l_physPathMatches( + i_entityPath); + + TARGETING::TargetRangeFilter l_targetsWithMatchingPhysPath( + TARGETING::targetService().begin(), + TARGETING::targetService().end(), + &l_physPathMatches); + + if(l_targetsWithMatchingPhysPath) { - case EntityPath::PATH_PHYSICAL: - found = ( (i_entityPath) - == (*iv_targets)[i].getAttr<ATTR_PHYS_PATH>()); - break; - case EntityPath::PATH_AFFINITY: - found = ( (i_entityPath) - == (*iv_targets)[i].getAttr<ATTR_AFFINITY_PATH>()); - break; - default: - break; + l_pTarget = *l_targetsWithMatchingPhysPath; + + #ifdef EXTRA_SANITY_CHECKING + ++l_targetsWithMatchingPhysPath; + if(l_targetsWithMatchingPhysPath) + { + TARG_ASSERT(0, TARG_ERR_LOC + "Should have found a single target with HUID of 0x%08X " + "when searching for physical path", + l_pTarget->getAttr<ATTR_HUID>()); + } + #endif } + } + else if(i_entityPath.type() == EntityPath::PATH_AFFINITY) + { + PredicateAttrVal<TARGETING::ATTR_AFFINITY_PATH> l_affinityPathMatches( + i_entityPath); - if (found) + TARGETING::TargetRangeFilter l_targetsWithMatchingAffinityPath( + TARGETING::targetService().begin(), + TARGETING::targetService().end(), + &l_affinityPathMatches); + + if(l_targetsWithMatchingAffinityPath) { - l_pTarget = &(*iv_targets)[i]; - break; + l_pTarget = *l_targetsWithMatchingAffinityPath; + + #ifdef EXTRA_SANITY_CHECKING + ++l_targetsWithMatchingAffinityPath; + if(l_targetsWithMatchingAffinityPath) + { + TARG_ASSERT(0, TARG_ERR_LOC + "Should have found a single target with HUID of 0x%08X " + "when searching for affinity path", + l_pTarget->getAttr<ATTR_HUID>()); + } + #endif } } + else + { + TARG_ERR("EntityPath Type [%s] not supported for toTarget Method", + i_entityPath.pathTypeAsString()); + } return l_pTarget; @@ -326,27 +597,175 @@ Target* TargetService::toTarget( //****************************************************************************** void TargetService::masterProcChipTargetHandle( - Target*& o_masterProcChipTargetHandle, - const uint8_t i_node) const + Target*& o_masterProcChipTargetHandle, + const Target* i_pNodeTarget) const { #define TARG_FN "masterProcChipTargetHandle(...)" + errlHndl_t pError = NULL; - Target* l_pTarget = NULL; + pError = queryMasterProcChipTargetHandle( + o_masterProcChipTargetHandle, + i_pNodeTarget); + if(pError != NULL) + { + /* Error is already traced w.r.t api called, not repeating here*/ + TARG_ERR("Not able to find the Master Proc Chip Target Handle"); + delete pError; + pError = NULL; + o_masterProcChipTargetHandle = NULL; + } + #undef TARG_FN +} + +//****************************************************************************** +// TargetService::queryMasterProcChipTargetHandle +//****************************************************************************** + +errlHndl_t TargetService::queryMasterProcChipTargetHandle( + Target*& o_masterProcChipTargetHandle, + const Target* const i_pNodeTarget) const +{ + #define TARG_FN "queryMasterProcChipTargetHandle(...)" + + errlHndl_t pError = NULL; + Target* pMasterProc = NULL; + o_masterProcChipTargetHandle = NULL; TARG_ASSERT(iv_initialized, TARG_ERR_LOC - "USAGE: TargetService not initialized"); + "USAGE: TargetService not initialized"); + + do { + + if(i_pNodeTarget == NULL) + { + static Target* pActingMasterTarget = NULL; + + if(!pActingMasterTarget || PLAT::PROPERTIES::MULTINODE_AWARE) + { + // Create filter that finds acting master processors + PredicateCTM procFilter(CLASS_CHIP, TYPE_PROC); + PredicateAttrVal<ATTR_PROC_MASTER_TYPE> actingMasterFilter( + PROC_MASTER_TYPE_ACTING_MASTER); + PredicatePostfixExpr actingMasterProcFilter; + actingMasterProcFilter.push(&procFilter).push( + &actingMasterFilter).And(); + + // Find all the acting master processors (max one per physical + // node), sorted by fabric node ID, and return the one with the + // lowest fabric node ID + TargetRangeFilter blueprintProcs( + targetService().begin(), + targetService().end(), + &actingMasterProcFilter); + + TARGETING::ATTR_FABRIC_NODE_ID_type minFabricNodeId = + TARGETING::FABRIC_NODE_ID_NOT_FOUND; + for(; blueprintProcs; ++blueprintProcs) + { + TARGETING::ATTR_FABRIC_NODE_ID_type fabricNodeId = + blueprintProcs->getAttr< + TARGETING::ATTR_FABRIC_NODE_ID>(); + if(fabricNodeId < minFabricNodeId) + { + minFabricNodeId = fabricNodeId; + pMasterProc = *blueprintProcs; + } + } + + if( (pMasterProc) + && (!PLAT::PROPERTIES::MULTINODE_AWARE)) + { + pActingMasterTarget = pMasterProc; + } + } + else + { + pMasterProc = pActingMasterTarget; + } + } - //@TODO RTC 78076 Need to query the actual hardware and cross check it with - // PNOR to determine the master chip - // target; for now, just always report sys0.n0.proc0 - EntityPath l_masterProcChipEntityPath(EntityPath::PATH_PHYSICAL); - l_masterProcChipEntityPath.addLast(TYPE_SYS, 0).addLast(TYPE_NODE, i_node) - .addLast(TYPE_PROC, 0); + /* We have a valid Target at this point */ + /* Would verify if the target given by user is a node target */ + else if( (i_pNodeTarget->getAttr<ATTR_CLASS>() == CLASS_ENC) && + (i_pNodeTarget->getAttr<ATTR_TYPE>() == TYPE_NODE) ) + { + // Create predicate which looks for an acting master processor chip + PredicateAttrVal<ATTR_PROC_MASTER_TYPE> l_procMasterMatches( + PROC_MASTER_TYPE_ACTING_MASTER); + PredicateCTM + l_procPredicate(TARGETING::CLASS_CHIP,TARGETING::TYPE_PROC); + PredicatePostfixExpr l_masterProcFilter; + l_masterProcFilter.push(&l_procPredicate).push( + &l_procMasterMatches).And(); + + // Find the acting master within the node + TARGETING::TargetHandleList l_masterProclist; + getAssociated(l_masterProclist, + const_cast<const Target*>(i_pNodeTarget), CHILD, ALL, + &l_masterProcFilter); + + if(!l_masterProclist.empty()) + { + pMasterProc = l_masterProclist[0]; + } + } + else + { + TARG_ERR("Invalid Node Target to query Master Proc " + "- NULL Master Proc Handle Returned. HUID of Target Passed " + "[0x%08X]", i_pNodeTarget->getAttr<ATTR_HUID>()); + + /*@ + * @errortype + * @refcode LIC_REFCODE + * @subsys EPUB_FIRMWARE_SP + * @moduleid TARG_MOD_QUERY_MASTER_PROC_CHIP + * @reasoncode TARG_RC_INVALID_NODE + * @userData1 HUID of Target Passed + * @devdesc Error: User Passed an invalid Node Target to find the + * master proc handle + */ + UTIL::createTracingError( + TARG_MOD_QUERY_MASTER_PROC_CHIP, + TARG_RC_INVALID_NODE, + i_pNodeTarget->getAttr<ATTR_HUID>(), + 0,0,0, + pError); + break; + } - l_pTarget = l_masterProcChipEntityPath.operator->(); + if(pMasterProc == NULL) + { + TARG_ERR("Failed to find acting master processor, given input node of " + "i_pNodeTarget = %p with HUID of 0x%08X",i_pNodeTarget, + i_pNodeTarget ? i_pNodeTarget->getAttr<ATTR_HUID>() : 0); + + /*@ + * @errortype + * @refcode LIC_REFCODE + * @subsys EPUB_FIRMWARE_SP + * @moduleid TARG_MOD_QUERY_MASTER_PROC_CHIP + * @reasoncode TARG_RC_TARGET_NOT_FOUND + * @userData1 HUID of Target Passed + * @devdesc Error: User Passed an invalid Node Target to find the + * master proc handle + */ + UTIL::createTracingError( + TARG_MOD_QUERY_MASTER_PROC_CHIP, + TARG_RC_TARGET_NOT_FOUND, + i_pNodeTarget ? i_pNodeTarget->getAttr<ATTR_HUID>() : 0, + 0,0,0, + pError); + break; + } + else + { + o_masterProcChipTargetHandle = pMasterProc; + } - o_masterProcChipTargetHandle = l_pTarget; + } while(0); + return pError; #undef TARG_FN } @@ -470,31 +889,36 @@ void TargetService::dump() const TARG_ASSERT(iv_initialized, TARG_ERR_LOC "USAGE: TargetService not initialized"); - TARG_INF("Targets (size=%d):", - sizeof(Target)*iv_maxTargets); + TARGETING::TargetRangeFilter l_allTargets( + TARGETING::targetService().raw_begin(), + TARGETING::targetService().raw_end(), + NULL); - for (uint32_t i = 0; i < iv_maxTargets; ++i) + uint32_t l_totalTargetCnt = 0; + for(;l_allTargets; ++l_allTargets) { + ++l_totalTargetCnt; TARG_INF( "[Target %d] " "Class = 0x%X, " "Type = 0x%X, " "Model = 0x%X", - i, - (*iv_targets)[i].getAttr<ATTR_CLASS>(), - (*iv_targets)[i].getAttr<ATTR_TYPE>(), - (*iv_targets)[i].getAttr<ATTR_MODEL>()); + l_totalTargetCnt, + l_allTargets->getAttr<ATTR_CLASS>(), + l_allTargets->getAttr<ATTR_TYPE>(), + l_allTargets->getAttr<ATTR_MODEL>()); + TARG_INF("Physical"); - (*iv_targets)[i].getAttr<ATTR_PHYS_PATH>().dump(); + l_allTargets->getAttr<ATTR_PHYS_PATH>().dump(); EntityPath l_entityPath; - if( (*iv_targets)[i].tryGetAttr<ATTR_AFFINITY_PATH>(l_entityPath) ) + if( l_allTargets->tryGetAttr<ATTR_AFFINITY_PATH>(l_entityPath) ) { TARG_INF("Affinity"); l_entityPath.dump(); } - if( (*iv_targets)[i].tryGetAttr<ATTR_POWER_PATH>(l_entityPath) ) + if( l_allTargets->tryGetAttr<ATTR_POWER_PATH>(l_entityPath) ) { TARG_INF("Power"); l_entityPath.dump(); @@ -502,24 +926,25 @@ void TargetService::dump() const DUMMY_RW_ATTR l_dummyRw; memset(l_dummyRw,0x00,sizeof(l_dummyRw)); - if ((*iv_targets)[i].tryGetAttr<ATTR_DUMMY_RW> (l_dummyRw)) + if (l_allTargets->tryGetAttr<ATTR_DUMMY_RW> (l_dummyRw)) { TARG_INF("Dummy = 0x%X", l_dummyRw[0][0][0]); } TARG_INF("Supports FSI SCOM = %d", - (*iv_targets)[i].getAttr<ATTR_PRIMARY_CAPABILITIES>() - .supportsFsiScom); + l_allTargets->getAttr< + ATTR_PRIMARY_CAPABILITIES>().supportsFsiScom); TARG_INF("Supports XSCOM SCOM = %d", - (*iv_targets)[i].getAttr<ATTR_PRIMARY_CAPABILITIES>() - .supportsXscom); + l_allTargets->getAttr< + ATTR_PRIMARY_CAPABILITIES>().supportsXscom); TARG_INF("Supports Inband SCOM = %d", - (*iv_targets)[i].getAttr<ATTR_PRIMARY_CAPABILITIES>() - .supportsInbandScom); + l_allTargets->getAttr< + ATTR_PRIMARY_CAPABILITIES>().supportsInbandScom); ScomSwitches l_switches = {0}; - if ( (*iv_targets)[i].tryGetAttr<ATTR_SCOM_SWITCHES>(l_switches) ) + if ( l_allTargets->tryGetAttr< + ATTR_SCOM_SWITCHES>(l_switches) ) { TARG_INF("Use FSI SCOM = %d",l_switches.useFsiScom); TARG_INF("Use XSCOM = %d",l_switches.useXscom); @@ -527,20 +952,22 @@ void TargetService::dump() const } uint64_t l_xscomBaseAddr = 0; - if ( (*iv_targets)[i].tryGetAttr<ATTR_XSCOM_BASE_ADDRESS>( - l_xscomBaseAddr) ) + if ( l_allTargets->tryGetAttr< + ATTR_XSCOM_BASE_ADDRESS>(l_xscomBaseAddr) ) { TARG_INF("XSCOM Base Address = 0x%016llX",l_xscomBaseAddr); } uint8_t l_Node_Id = 0; - if ( (*iv_targets)[i].tryGetAttr<ATTR_FABRIC_NODE_ID>(l_Node_Id)) + if ( l_allTargets->tryGetAttr< + ATTR_FABRIC_NODE_ID>(l_Node_Id)) { TARG_INF("XSCOM Node ID = 0x%X",l_Node_Id); } uint8_t l_Chip_Id = 0; - if ( (*iv_targets)[i].tryGetAttr<ATTR_FABRIC_CHIP_ID>(l_Chip_Id)) + if ( l_allTargets->tryGetAttr< + ATTR_FABRIC_CHIP_ID>(l_Chip_Id)) { TARG_INF("XSCOM Chip ID = 0x%X",l_Chip_Id); } @@ -564,7 +991,8 @@ bool TargetService::writeSectionData( bool l_response = false; if(i_pages.size() != 0) { - l_response = TARG_GET_SINGLETON(TARGETING::theAttrRP).writeSectionData(i_pages); + l_response = + TARG_GET_SINGLETON(TARGETING::theAttrRP).writeSectionData(i_pages); } TARG_EXIT(); @@ -576,14 +1004,15 @@ bool TargetService::writeSectionData( // TargetService::readSectionData //****************************************************************************** void TargetService::readSectionData( - std::vector <sectionRefData>& o_pages, - const SECTION_TYPE i_sectionId) + std::vector <sectionRefData>& o_pages, + const SECTION_TYPE i_sectionId, + const NODE_ID i_nodeId) { #define TARG_FN "readSectionData(...)" TARG_ENTER(); TARG_GET_SINGLETON(TARGETING::theAttrRP).readSectionData( - o_pages, i_sectionId); + o_pages, i_sectionId, i_nodeId); TARG_EXIT(); @@ -594,24 +1023,28 @@ void TargetService::readSectionData( // TargetService::_configureTargetPool //****************************************************************************** -void TargetService::_configureTargetPool() +void TargetService::_configureTargetPool( + NodeSpecificInfo& i_nodeInfoContainer) { #define TARG_FN "_configureTargetPool(...)" TARG_ENTER(); - _maxTargets(); + _maxTargets(i_nodeInfoContainer); // iv_pPnor--> points to uint32_t* --> points to --> uint32_t, targets[] // (uint32_t*)+1 --> points to ------------> targets[] const AbstractPointer<uint32_t>* ppNumTargets - = static_cast<const AbstractPointer<uint32_t>*>(iv_pPnor); - iv_targets = + = static_cast<const AbstractPointer<uint32_t>*>( + i_nodeInfoContainer.pPnor); + + i_nodeInfoContainer.targets = reinterpret_cast< Target(*)[] > ( (TARG_TO_PLAT_PTR_AND_INC(*ppNumTargets,1))); - TARG_ASSERT(iv_targets, TARG_ERR_LOC + + TARG_ASSERT(i_nodeInfoContainer.targets, TARG_ERR_LOC "FATAL: Could not determine location of targets"); - TARG_INF("iv_targets = %p", iv_targets); + TARG_INF("i_nodeInfoContainer.targets = %p", i_nodeInfoContainer.targets); // Only translate addresses on platforms where addresses are 4 bytes wide // (FSP). The compiler should perform dead code elimination of this path on @@ -619,13 +1052,14 @@ void TargetService::_configureTargetPool() // can be statically computed at compile time. if(TARG_ADDR_TRANSLATION_REQUIRED) { - iv_targets = static_cast<Target(*)[]>( - TARG_GET_SINGLETON(TARGETING::theAttrRP).translateAddr( - iv_targets)); - TARG_ASSERT(iv_targets, TARG_ERR_LOC + i_nodeInfoContainer.targets = static_cast<Target(*)[]>( + TARG_GET_SINGLETON(TARGETING::theAttrRP).translateAddr( + i_nodeInfoContainer.targets, i_nodeInfoContainer.nodeId)); + TARG_ASSERT(i_nodeInfoContainer.targets, TARG_ERR_LOC "FATAL: Could not determine location of targets after " "address translation"); - TARG_INF("iv_targets after translation = %p", iv_targets); + TARG_INF("i_nodeInfoContainer.targets after translation = %p", + i_nodeInfoContainer.targets); } TARG_EXIT(); @@ -637,14 +1071,15 @@ void TargetService::_configureTargetPool() // TargetService::_maxTargets //****************************************************************************** -uint32_t TargetService::_maxTargets() +void TargetService::_maxTargets(NodeSpecificInfo& io_nodeInfoContainer) { #define TARG_FN "_maxTargets(...)" // Target count found by following the pointer pointed to by the iv_pPnor // pointer. const AbstractPointer<uint32_t>* pNumTargetsPtr - = static_cast<const AbstractPointer<uint32_t>*>(iv_pPnor); + = static_cast<const AbstractPointer<uint32_t>*>( + io_nodeInfoContainer.pPnor); uint32_t* pNumTargets = TARG_TO_PLAT_PTR(*pNumTargetsPtr); // Only translate addresses on platforms where addresses are 4 bytes wide @@ -655,18 +1090,16 @@ uint32_t TargetService::_maxTargets() { pNumTargets = static_cast<uint32_t*>( TARG_GET_SINGLETON(TARGETING::theAttrRP).translateAddr( - pNumTargets)); + pNumTargets, io_nodeInfoContainer.nodeId)); } TARG_ASSERT(pNumTargets, TARG_ERR_LOC "FATAL: Could not determine location of targets after " "address translation"); - iv_maxTargets = *pNumTargets; - - TARG_INF("Max targets = %d",iv_maxTargets); + io_nodeInfoContainer.maxTargets = *pNumTargets; - return iv_maxTargets; + TARG_INF("Max targets = %d", io_nodeInfoContainer.maxTargets); #undef TARG_FN } @@ -687,17 +1120,26 @@ void TargetService::_getInwards( while (i_entityPath.size() > 1) { i_entityPath.removeLast(); - for (uint32_t i = 0; i < iv_maxTargets; ++i) + + TargetIterator l_allTargets; + + for(l_allTargets = targetService().begin(); + l_allTargets != targetService().end(); + ++l_allTargets) { EntityPath l_candidatePath; - bool l_candidateFound = tryGetPath(i_attr, &(*iv_targets)[i], - l_candidatePath); - if ( l_candidateFound - && (l_candidatePath == i_entityPath) - && ( (i_pPredicate == NULL) - || (*i_pPredicate)( &(*iv_targets)[i]) ) ) + bool l_candidateFound = false; + + l_candidateFound = tryGetPath(i_attr, + (*l_allTargets), + l_candidatePath); + + if ( (l_candidateFound) + && (l_candidatePath == i_entityPath) + && ( (i_pPredicate == NULL) + || (*i_pPredicate)(*l_allTargets) ) ) { - o_list.push_back(&(*iv_targets)[i]); + o_list.push_back(*l_allTargets); break; } } @@ -722,40 +1164,267 @@ void TargetService::_getOutwards( const PredicateBase* const i_pPredicate, TargetHandleList& o_list) const { - #define TARG_FN "_getOutwards()...)" + #define TARG_FN "_getOutwards(...)" + do + { + // If at max depth (a leaf path element), no children possible + if (i_entityPath.size() >= EntityPath::MAX_PATH_ELEMENTS) + { + break; + } - do { + // Find the children (immediate, or all), depending on recursion level + TargetIterator l_allTargets; - // If at max depth (a leaf path element), no children possible - if (i_entityPath.size() >= EntityPath::MAX_PATH_ELEMENTS) + for(l_allTargets = targetService().begin(); + l_allTargets != targetService().end(); + ++l_allTargets) + { + EntityPath l_candidatePath; + bool l_candidateFound = tryGetPath(i_attr, *l_allTargets, + l_candidatePath); + if (l_candidateFound) + { + if ( ( (i_recursionLevel == IMMEDIATE) + && (l_candidatePath.size() == i_entityPath.size() +1)) + || ( (i_recursionLevel == ALL) + && (l_candidatePath.size() > i_entityPath.size()))) + { + if (i_entityPath.equals(l_candidatePath,i_entityPath.size()) + && ( (i_pPredicate == NULL) + || (*i_pPredicate)(*l_allTargets) ) ) + { + o_list.push_back(*l_allTargets); + } + } + } + } + + } while (0); + + #undef TARG_FN +} + +//****************************************************************************** +// TargetService::setMasterNode +//****************************************************************************** +errlHndl_t TargetService::setMasterNode(const Target* i_pTarget) +{ + #define TARG_FN "setMasterNode(...)" + errlHndl_t pError = NULL; + + TARG_ASSERT(i_pTarget != NULL, TARG_ERR_LOC + "Error: User cannot pass NULL Target in place of Node Target"); + + // Check for Node Target + PredicateCTM l_nodePredicate(CLASS_ENC, TYPE_NODE); + if(l_nodePredicate(i_pTarget)) { - break; + pError = UTIL::setMasterNode(const_cast<Target*>(i_pTarget)); + if(pError) + { + TARG_ERR("Master Node Attribute Set Failed for Node [0x%08X]", + i_pTarget->getAttr<ATTR_HUID>()); + } + } + else + { + // Create Error + /*@ + * @errortype + * @refcode LIC_REFCODE + * @subsys EPUB_FIRMWARE_SP + * @moduleid TARG_MOD_SET_MASTER_NODE + * @reasoncode TARG_RC_INVALID_NODE + * @userData1 HUID of Target Passed + * @devdesc Error: User Passed an invalid Node Target + */ + UTIL::createTracingError( + TARG_MOD_SET_MASTER_NODE, + TARG_RC_INVALID_NODE, + i_pTarget->getAttr<ATTR_HUID>(), + 0,0,0, + pError); } - // Find the children (immediate, or all), depending on recursion level - for (uint32_t i = 0; i < iv_maxTargets; ++i) + return pError; + #undef TARG_FN +} + +//****************************************************************************** +// TargetService::isNonMasterNodeSystemTarget +//****************************************************************************** + +bool TargetService::isNonMasterNodeSystemTarget(const Target* i_pTarget) const +{ + #define TARG_FN "isNonMasterNodeSystemTarget(...)" + + Target* l_pTarget = const_cast<Target*>(i_pTarget); + bool l_isNonMasterNodeSystemTarget = false; + TARG_ASSERT(l_pTarget != NULL, TARG_ERR_LOC + "Cannot pass a NULL Target"); + + if( (l_pTarget->getAttr<ATTR_CLASS>() == CLASS_SYS) && + (l_pTarget->getAttr<ATTR_TYPE>() == TYPE_SYS) ) { - EntityPath l_candidatePath; - bool l_candidateFound = tryGetPath(i_attr, &(*iv_targets)[i], - l_candidatePath); - if (l_candidateFound) + if(true == UTIL::isNonMasterNodeSystemTarget(i_pTarget)) { - if ( ( (i_recursionLevel == IMMEDIATE) - && (l_candidatePath.size() == i_entityPath.size() + 1)) - || ( (i_recursionLevel == ALL) - && (l_candidatePath.size() > i_entityPath.size()))) + l_isNonMasterNodeSystemTarget = true; + } + } + return l_isNonMasterNodeSystemTarget; + #undef TARG_FN +} + +//****************************************************************************** +// TargetService::getNumInitializedNodes +//****************************************************************************** + +uint8_t TargetService::getNumInitializedNodes() const +{ + #define TARG_FN "getNumInitializedNodes(...)" + return MAX_NODE_ID; + #undef TARG_FN +} + +//****************************************************************************** +// TargetService::initDefaultMasterNode +//****************************************************************************** + +void TargetService::initDefaultMasterNode() +{ + #define TARG_FN "initDefaultMasterNode(...)" + TARG_ENTER(); + errlHndl_t pError = NULL; + if(!iv_initialized) + { + TARG_INF("Default Master Node Selection Mode"); + + // See if we already have a persistent Master node from previous run + // We have to go via this route since iv_initialized flag is not set, + // so we can't use any targetservice api to do this. Have to manual go + // over. + for(uint8_t l_nodeCnt=0; l_nodeCnt<MAX_NODE_ID; ++l_nodeCnt) + { + if((iv_nodeInfo[l_nodeCnt].initialized) && + (iv_nodeInfo[l_nodeCnt].maxTargets > 0)) { - if ( i_entityPath.equals(l_candidatePath,i_entityPath.size()) - && ( (i_pPredicate == NULL) - || (*i_pPredicate)( &(*iv_targets)[i]) ) ) + for(uint32_t l_targetCnt=0; + l_targetCnt<iv_nodeInfo[l_nodeCnt].maxTargets; + ++l_targetCnt) + { + if(((*(iv_nodeInfo[l_nodeCnt].targets))[ + l_targetCnt].getAttr<ATTR_CLASS>() == CLASS_ENC) && + ((*(iv_nodeInfo[l_nodeCnt].targets))[ + l_targetCnt].getAttr<ATTR_TYPE>() == TYPE_NODE)) + { + if(UTIL::isThisMasterNodeTarget( + &((*(iv_nodeInfo[l_nodeCnt].targets))[l_targetCnt]))) + { + // We have found a previous instance of master node + // target, no need for sync here, since it would + // have been taken care of when we updated the + // master node last time around. + iv_initialized = true; + TARG_INF("Previous Master Node Instance Found - " + "Node [%d]", l_nodeCnt); + break; + } + } + } + if(iv_initialized) + { + break; + } + } + } + if(!iv_initialized) + { + TARG_INF("No previous master node found.. Setting a default one"); + for(uint8_t l_nodeCnt=0; l_nodeCnt<MAX_NODE_ID; ++l_nodeCnt) + { + if((iv_nodeInfo[l_nodeCnt].initialized) && + (iv_nodeInfo[l_nodeCnt].maxTargets > 0)) { - o_list.push_back(&(*iv_targets)[i]); + // Need to go over each target to search for Node, cannot + // use rangefilter here since targeting is yet not + // initialized. + for(uint32_t l_targetCnt=0; + l_targetCnt<iv_nodeInfo[l_nodeCnt].maxTargets; + ++l_targetCnt) + { + if(((*(iv_nodeInfo[l_nodeCnt].targets))[ + l_targetCnt].getAttr<ATTR_CLASS>() == CLASS_ENC) && + ((*(iv_nodeInfo[l_nodeCnt].targets))[ + l_targetCnt].getAttr<ATTR_TYPE>() == TYPE_NODE)) + { + // Just do bare minimum stuff i.e. just set the + // Master Node Attribute + pError = UTIL::setDefaultMasterNodeWithoutSync( + &((*(iv_nodeInfo[l_nodeCnt].targets))[ + l_targetCnt])); + if(pError) + { + TARG_ERR("Setting of default master node " + "target failed"); + TARG_ASSERT(0, TARG_ERR_LOC + "Default Master Node Set Failed at" + " Init time"); + } + iv_initialized = true; + break; + } + } + if(iv_initialized == true) + { + // We have setted the default Master Node, let's just + // sync it up. + // Above we had to callup special mode to set Master + // node, since targeting is not initalized yet, cannot + // use the basic features of predicates, rangefilter + // and all. + Target* l_pSysTarget = NULL; + getTopLevelTarget(l_pSysTarget); + TARG_ASSERT(l_pSysTarget != NULL, TARG_ERR_LOC + "Top Level Target cannot be NULL"); + pError = UTIL::SyncMasterSystemTarget(l_pSysTarget); + if(pError) + { + TARG_ASSERT(0, TARG_ERR_LOC + "System Target Sync has failed at Init Time"); + } + break; + } } } } } + else + { + TARG_INF("TargetService already initialized"); + } + TARG_EXIT(); + #undef TARG_FN +} - } while (0); +//****************************************************************************** +// TargetService::getMasterNodeTarget +//****************************************************************************** + +void TargetService::getMasterNodeTarget( + Target*& o_masterNodeTarget) const +{ + #define TARG_FN "getMasterNodeTarget(...)" + + TARG_ASSERT(iv_initialized, TARG_ERR_LOC + "USAGE: TargetService not initialized"); + + // Keep the user target handle initialize to NULL + o_masterNodeTarget = NULL; + UTIL::getMasterNodeTarget(o_masterNodeTarget); + + TARG_ASSERT(o_masterNodeTarget != NULL, TARG_ERR_LOC + "Node Target of the System's Master Node cannot be NULL"); #undef TARG_FN } diff --git a/src/usr/targeting/common/xmltohb/attribute_types.xml b/src/usr/targeting/common/xmltohb/attribute_types.xml index f93bb1b89..4f0b42477 100644 --- a/src/usr/targeting/common/xmltohb/attribute_types.xml +++ b/src/usr/targeting/common/xmltohb/attribute_types.xml @@ -12697,4 +12697,39 @@ firmware notes: Platforms should initialize this attribute to AUTO (0)</descript </hwpfToHbAttrMap> </attribute> +<enumerationType> + <id>PROC_MASTER_TYPE</id> + <description> + Enumeration indicating the role of proc as master/alt_master/not_master + </description> + <enumerator> + <name>ACTING_MASTER</name> + <value>0</value> + </enumerator> + <enumerator> + <name>MASTER_CANDIDATE</name> + <value>1</value> + </enumerator> + <enumerator> + <name>NOT_MASTER</name> + <value>2</value> + </enumerator> + <default>NOT_MASTER</default> +</enumerationType> + +<attribute> + <id>PROC_MASTER_TYPE</id> + <description>Type of Master, ACTING_MASTER or MASTER_CANDIDATE or + NOT_MASTER</description> + <simpleType> + <enumeration> + <id>PROC_MASTER_TYPE</id> + </enumeration> + </simpleType> + <persistency>non-volatile</persistency> + <hasStringConversion/> + <readable/> + <writeable/> +</attribute> + </attributes> diff --git a/src/usr/targeting/common/xmltohb/common.mk b/src/usr/targeting/common/xmltohb/common.mk index 8561911fd..c9ca8f874 100644 --- a/src/usr/targeting/common/xmltohb/common.mk +++ b/src/usr/targeting/common/xmltohb/common.mk @@ -37,14 +37,16 @@ XMLTOHB_HEADER_TARGETS = \ pnortargeting.H \ fapiplatattrmacros.H \ test_ep.H \ - mapattrmetadata.H + mapattrmetadata.H \ + mapsystemattrsize.H XMLTOHB_SOURCE_TARGETS = \ attributestrings.C \ attributedump.C \ errludattribute.C \ errludtarget.C \ - mapattrmetadata.C + mapattrmetadata.C \ + mapsystemattrsize.C XMLTOHB_SYSTEM_BINARIES = \ vbu_VENICE_targeting.bin \ diff --git a/src/usr/targeting/common/xmltohb/simics_MURANO.system.xml b/src/usr/targeting/common/xmltohb/simics_MURANO.system.xml index 436c99e9f..c193d4a38 100644 --- a/src/usr/targeting/common/xmltohb/simics_MURANO.system.xml +++ b/src/usr/targeting/common/xmltohb/simics_MURANO.system.xml @@ -264,6 +264,10 @@ <targetInstance> <id>sys0node0proc0</id> <type>chip-processor-murano</type> + <attribute> + <id>PROC_MASTER_TYPE</id> + <default>ACTING_MASTER</default> + </attribute> <attribute><id>HUID</id><default>0x00050000</default></attribute> <attribute><id>POSITION</id><default>0</default></attribute> <attribute><id>SCOM_SWITCHES</id> diff --git a/src/usr/targeting/common/xmltohb/simics_VENICE.system.xml b/src/usr/targeting/common/xmltohb/simics_VENICE.system.xml index c5c822068..3487069cb 100644 --- a/src/usr/targeting/common/xmltohb/simics_VENICE.system.xml +++ b/src/usr/targeting/common/xmltohb/simics_VENICE.system.xml @@ -237,6 +237,10 @@ <targetInstance> <id>sys0node0proc0</id> <type>chip-processor-venice</type> + <attribute> + <id>PROC_MASTER_TYPE</id> + <default>ACTING_MASTER</default> + </attribute> <attribute><id>HUID</id><default>0x00050000</default></attribute> <attribute><id>POSITION</id><default>0</default></attribute> <attribute><id>SCOM_SWITCHES</id> diff --git a/src/usr/targeting/common/xmltohb/target_types.xml b/src/usr/targeting/common/xmltohb/target_types.xml index 977b3927f..f3813d51e 100644 --- a/src/usr/targeting/common/xmltohb/target_types.xml +++ b/src/usr/targeting/common/xmltohb/target_types.xml @@ -260,6 +260,10 @@ <default>PROC</default> </attribute> <attribute> + <id>PROC_MASTER_TYPE</id> + <default>NOT_MASTER</default> + </attribute> + <attribute> <id>PRIMARY_CAPABILITIES</id> <default> <field><id>supportsFsiScom</id><value>1</value></field> diff --git a/src/usr/targeting/common/xmltohb/vbu_MURANO.system.xml b/src/usr/targeting/common/xmltohb/vbu_MURANO.system.xml index b836f02ca..125574a86 100644 --- a/src/usr/targeting/common/xmltohb/vbu_MURANO.system.xml +++ b/src/usr/targeting/common/xmltohb/vbu_MURANO.system.xml @@ -252,6 +252,10 @@ <targetInstance> <id>sys0node0proc0</id> <type>chip-processor-murano</type> + <attribute> + <id>PROC_MASTER_TYPE</id> + <default>ACTING_MASTER</default> + </attribute> <attribute><id>HUID</id><default>0x00050000</default></attribute> <attribute><id>POSITION</id><default>0</default></attribute> <attribute><id>SCOM_SWITCHES</id> diff --git a/src/usr/targeting/common/xmltohb/vbu_VENICE.system.xml b/src/usr/targeting/common/xmltohb/vbu_VENICE.system.xml index 90f549c3c..697eb90db 100644 --- a/src/usr/targeting/common/xmltohb/vbu_VENICE.system.xml +++ b/src/usr/targeting/common/xmltohb/vbu_VENICE.system.xml @@ -253,6 +253,10 @@ <targetInstance> <id>sys0node0proc0</id> <type>chip-processor-venice</type> + <attribute> + <id>PROC_MASTER_TYPE</id> + <default>ACTING_MASTER</default> + </attribute> <attribute><id>HUID</id><default>0x00050000</default></attribute> <attribute><id>POSITION</id><default>0</default></attribute> <attribute><id>SCOM_SWITCHES</id> diff --git a/src/usr/targeting/common/xmltohb/xmltohb.pl b/src/usr/targeting/common/xmltohb/xmltohb.pl index 335944862..3d519631a 100755 --- a/src/usr/targeting/common/xmltohb/xmltohb.pl +++ b/src/usr/targeting/common/xmltohb/xmltohb.pl @@ -115,6 +115,8 @@ if($cfgVerbose) ################################################################################ use constant INVALID_HUID=>0xffffffff; +use constant PEER_HUID_NOT_PRESENT=>0xfffffffe; + my $xml = new XML::Simple (KeyAttr=>[]); use Digest::MD5 qw(md5_hex); @@ -264,6 +266,22 @@ if( !($cfgSrcOutputDir =~ "none") ) writeAttrMetadataMapCFile($attributes,$attrMetadataMapCFile); writeAttrMetadataMapCFileFooter($attrMetadataMapCFile); close $attrMetadataMapCFile; + + open(MAP_ATTR_SIZE_H_FILE,">$cfgSrcOutputDir"."mapsystemattrsize.H") + or fatal ("Attribute size map file Header: \"$cfgSrcOutputDir" + . "mapsystemattrsize.H\" could not be opened."); + my $attrSizeMapHFile = *MAP_ATTR_SIZE_H_FILE; + writeAttrSizeMapHFile($attrSizeMapHFile); + close $attrSizeMapHFile; + + open(MAP_ATTR_SIZE_C_FILE,">$cfgSrcOutputDir"."mapsystemattrsize.C") + or fatal ("Attribute size map file: \"$cfgSrcOutputDir" + . "mapsystemattrsize.C\" could not be opened."); + my $attrSizeMapCFile = *MAP_ATTR_SIZE_C_FILE; + writeAttrSizeMapCFileHeader($attrSizeMapCFile); + writeAttrSizeMapCFile($attributes,$attrSizeMapCFile); + writeAttrSizeMapCFileFooter($attrSizeMapCFile); + close $attrSizeMapCFile; } if( !($cfgImgOutputDir =~ "none") ) @@ -468,16 +486,27 @@ sub handleTgtPtrAttributesFsp if (exists $attr->{default}) { if( ($attr->{default} ne "NULL") - && ($attr->{id} eq "PEER_TARGET")) + && ($attr->{id} eq "PEER_TARGET") ) { - my $peerHUID = getPeerHuid(${$attributes}, - $attr->{default}); + my $peerHUID = INVALID_HUID; + $peerHUID = getPeerHuid($targetInstance); if($peerHUID == INVALID_HUID) { - fatal("HUID for Peer Target not found"); + fatal("HUID for Peer Target not found for " + . "Peer Target [$attr->{default}]\n"); + } + elsif($peerHUID == PEER_HUID_NOT_PRESENT) + { + # Might require this for debug, so keeping it. + #print STDOUT "****PEER HUID Attribut not present for " + # . "Peer Target [$attr->{default}]... Skip\n"; + $attr->{default} = "NULL"; + } + else + { + $attr->{default} = + sprintf("0x%X",(hex($peerHUID) << 32)); } - $attr->{default} = (hex($peerHUID) << 32); - $attr->{default} = sprintf("0x%X",$attr->{default}); } } } @@ -531,9 +560,10 @@ sub handleTgtPtrAttributesHb{ } else { - fatal("$attr->{id} attribute has an unknown value " - . "$attr->{default}\n" - . "It must be NULL or a valid PHYS_PATH\n"); + print STDOUT ("$attr->{id} attribute has an unknown value " + . "$attr->{default}\n" + . "It must be NULL or a valid PHYS_PATH\n"); + $attr->{default} = "NULL"; } } } @@ -542,42 +572,27 @@ sub handleTgtPtrAttributesHb{ sub getPeerHuid { - my($attributes, $peerPhysPath) = @_; + my($targetInstance) = @_; my $peerHUID = INVALID_HUID; - my $found = 0; - foreach my $targetInstance (@{$attributes->{targetInstance}}) + if(exists $targetInstance->{compileAttribute}->{id}) { - foreach my $attr (@{$targetInstance->{attribute}}) + if ($targetInstance->{compileAttribute}->{id} eq "PEER_HUID") { - 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; - } - } - } + $peerHUID = $targetInstance->{compileAttribute}->{default}; } - if($found) + else { - last; + fatal("We should have only PEER_HUID as compileAttribute. " + . "Don't know how to handle this Attribute " + . "$targetInstance->{compileAttribute}->{id}\n"); } } - + else + { + # PEER HUID doesn't exist, Return an pre-defined HUID which is invalid + $peerHUID = PEER_HUID_NOT_PRESENT; + } return $peerHUID; } @@ -3093,6 +3108,302 @@ sub writeTargetErrlHFile { print $outFile "#endif\n"; } # sub writeTargetErrlHFile +################################################################################ +# Writes the map system attr size C file header +################################################################################ + +sub writeAttrSizeMapCFileHeader { + my($outFile) = @_; + +print $outFile <<VERBATIM; + +/** + * \@file mapsystemattrsize.C + * + * \@brief Interface to get the map of system target attributes with respective + * attribute size + */ + +// STD +#include <map> + +// TARG +#include <mapsystemattrsize.H> + + +//****************************************************************************** +// Macros +//****************************************************************************** + +#undef TARG_NAMESPACE +#undef TARG_CLASS +#undef TARG_FUNC + +//****************************************************************************** +// Implementation +//****************************************************************************** + +namespace TARGETING +{ + + +#define TARG_NAMESPACE "TARGETING::" +#define TARG_CLASS "MapSystemAttrSize::" + +//****************************************************************************** +// TARGETING::mapSystemAttrSize +//****************************************************************************** + +TARGETING::MapSystemAttrSize& mapSystemAttrSize() +{ + #define TARG_FN "mapSystemAttrSize()" + + return TARG_GET_SINGLETON(TARGETING::theMapSystemAttrSize); + + #undef TARG_FN +} + +//****************************************************************************** +// TARGETING::MapSystemAttrSize::~MapSystemAttrSize +//****************************************************************************** + +MapSystemAttrSize::~MapSystemAttrSize() +{ + #define TARG_FN "~MapSystemAttrSize()" + #undef TARG_FN +} + +//****************************************************************************** +// TARGETING::MapSystemAttrSize::getMapForWriteableSystemAttributes +//****************************************************************************** + +const AttrSizeMapper& +MapSystemAttrSize::getMapForWriteableSystemAttributes() const +{ + #define TARG_FN "getMapForWriteableSystemAttributes()" + TARG_ENTER(); + + TARG_EXIT(); + return iv_mapSysAttrSize; + + #undef TARG_FN +} + +//****************************************************************************** +// TARGETING::MapSystemAttrSize::MapSystemAttrSize +//****************************************************************************** + +MapSystemAttrSize::MapSystemAttrSize() +{ + #define TARG_FN "MapSystemAttrSize()" +VERBATIM + +} + +###### +# Create a .C file to put System Target Attributes along with there respective +# Size in a map file +###### +sub writeAttrSizeMapCFile{ + my($attributes,$outFile) = @_; + my %finalAttrhash = (); + + # look for type sys-sys-power8 and store all attributes associated + foreach my $targetType (@{$attributes->{targetType}}) + { + if($targetType->{id} =~ m/^sys-sys-/) + { + my %attrhash = (); + getTargetAttributes($targetType->{id}, $attributes,\%attrhash); + foreach my $key ( keys %attrhash ) + { + foreach my $attr (@{$attributes->{attribute}}) + { + if($attr->{id} eq $key) + { + if((exists $attr->{writeable}) && + (!(exists $attr->{hbOnly}))) + { + # we have the attr here.. calculate the size + my $keyVal = "ATTR_"."$key"."_type"; + if(exists $attr->{simpleType}) + { + if(exists $attr->{simpleType}->{array}) + { + my @splitArrSize = split(',', + $attr->{simpleType}->{array}); + foreach my $num (@splitArrSize) + { + $keyVal = "$keyVal"."[$num]"; + } + } + elsif(exists $attr->{simpleType}->{string}) + { + if(exists $attr->{simpleType}->{string}-> + {sizeInclNull}) + { + $keyVal = "$keyVal"."[$attr-> + {simpleType}->{string}-> + {sizeInclNull}]"; + } + } + $finalAttrhash{$key} = $keyVal; + } + elsif(exists $attr->{complexType}) + { + $finalAttrhash{$key} = $keyVal; + } + elsif(exists $attr->{nativeType}) + { + $finalAttrhash{$key} = $keyVal; + } + else + { + print STDOUT "\t// Attribute $key is writable " + . "& Not Supported \n"; + } + } + } + } + } + } + } + print $outFile "\n"; + foreach my $key ( keys %finalAttrhash) + { + print $outFile " iv_mapSysAttrSize[ATTR_" + . "$key] = sizeof($finalAttrhash{$key});\n"; + } + print $outFile "\n"; +} + +################################################################################ +# Writes the map system attr size C file Footer +################################################################################ + +sub writeAttrSizeMapCFileFooter { + my($outFile) = @_; + + print $outFile <<VERBATIM; + #undef TARG_FN +} + +}// namespace TARGETING + +VERBATIM +} + +###### +# Create a .H file to put System Target Attributes along with their respective +# Size in a map file +###### +sub writeAttrSizeMapHFile{ + my($outFile) = @_; + print $outFile <<VERBATIM; + +#ifndef MAPSYSTEMATTRSIZE_H +#define MAPSYSTEMATTRSIZE_H + +/** + * \@file mapsystemattrsize.H + * + * \@brief Interface to get the map of system target attributes with respective + * attribute size + */ + +// STD +#include <map> + +// TARG +#include <targeting/common/trace.H> +#include <targeting/common/target.H> + +//****************************************************************************** +// Macros +//****************************************************************************** + +#undef TARG_NAMESPACE +#undef TARG_CLASS +#undef TARG_FUNC + +//****************************************************************************** +// Interface +//****************************************************************************** + +namespace TARGETING +{ + +class MapSystemAttrSize; + +/** + * \@brief Return the MapSystemAttrSize singleton instance + * + * \@return Reference to the MapSystemAttrSize singleton + */ +TARGETING::MapSystemAttrSize& mapSystemAttrSize(); + + +#define TARG_NAMESPACE "MAPSYSTEMATTRSIZE::" + +#define TARG_CLASS "MapSystemAttrSize::" + +/* + * \@brief Typedef map <attr, attSize> + */ +typedef map<ATTRIBUTE_ID, uint32_t> AttrSizeMapper; + +class MapSystemAttrSize +{ + + public: + /** + * \@brief Destroy the MapSystemAttrSize class + */ + ~MapSystemAttrSize(); + + /** + * \@brief Create the MapSystemAttrSize class + */ + MapSystemAttrSize(); + + /* + * \@brief returns the map of Writeable System attributes as Key and + * size of the attributes as value. + * + * \@return, returns the map which has the Writeable Sytem attributes + * as key and size as value pair, variable <SYSTEM_ATTRIBUTE_ID::Size> + */ + const AttrSizeMapper& getMapForWriteableSystemAttributes() const; + + private: + + /* Map variable for System Attribute Ids Vs the Size */ + AttrSizeMapper iv_mapSysAttrSize; + + /* Disable Copy constructor and assignment operator */ + MapSystemAttrSize( + const MapSystemAttrSize& i_right); + + MapSystemAttrSize& operator = ( + const MapSystemAttrSize& i_right); +}; + +/** + * \@brief Provide singleton access to the MapSystemAttrSize + */ +TARG_DECLARE_SINGLETON(TARGETING::MapSystemAttrSize, theMapSystemAttrSize); + +#undef TARG_CLASS +#undef TARG_NAMESPACE + + +}// namespace TARGETING + +#endif // MAPSYSTEMATTRSIZE_H + +VERBATIM + +} sub UTILITY_FUNCTIONS { } @@ -3409,13 +3720,25 @@ sub getInstantiatedTargetTypes { my %seen = (); my @uniqueTargetTypes = (); + my $targetCount = 0; + my $moveSysTarget = 0; + # To simplify the iterator code, always move a system target that appears as + # the first target to the next position foreach my $targetInstance (@{$attributes->{targetInstance}}) { + if(($targetInstance->{type} =~ m/^sys-sys-/) && ($targetCount == 0)) + { + $targetCount = $targetCount + 1; + $moveSysTarget = 1; + } push (@uniqueTargetTypes, $targetInstance->{type}) unless $seen{$targetInstance->{type}}++; } - + if($moveSysTarget == 1) + { + @uniqueTargetTypes[0,1] = @uniqueTargetTypes[1,0]; + } return @uniqueTargetTypes; } @@ -4412,10 +4735,28 @@ sub generateTargetingImage { # for code update. At minimum, ensure that we always process at this level # in the given order my @targetsAoH = (); + my $targetCount = 0; + my $moveSysTarget = 0; + + # To support the iterator code, we dont want sys target to be the + # first in order. So we have specifically moved system target to second, + # if it is in first place. foreach my $targetInstance (@{$attributes->{targetInstance}}) { + # for the first Target, check if Sys Target + if(($targetCount == 0) && ($targetInstance->{id} eq "sys0")) + { + # mark a flag here that we need to interchange 1&2 targets, + # so as to push system target to second place + $moveSysTarget = 1; + $targetCount = $targetCount + 1; + } push(@targetsAoH, $targetInstance); } + if($moveSysTarget == 1) + { + @targetsAoH[0,1] = @targetsAoH[1,0]; + } my $numTargets = @targetsAoH; my $numAttributes = 0; diff --git a/src/usr/targeting/makefile b/src/usr/targeting/makefile index b9179107f..876c99134 100644 --- a/src/usr/targeting/makefile +++ b/src/usr/targeting/makefile @@ -43,7 +43,8 @@ VPATH = \ ATTR_RP_OBJS = \ attrrp.o \ - attrsync.o + attrsync.o \ + targplatutil.o ENTRY_POINT_OBJS = \ targetservicestart.o diff --git a/src/usr/targeting/targplatutil.C b/src/usr/targeting/targplatutil.C new file mode 100644 index 000000000..f913030e2 --- /dev/null +++ b/src/usr/targeting/targplatutil.C @@ -0,0 +1,110 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/usr/targeting/targplatutil.C $ */ +/* */ +/* IBM CONFIDENTIAL */ +/* */ +/* COPYRIGHT International Business Machines Corp. 2013 */ +/* */ +/* p1 */ +/* */ +/* Object Code Only (OCO) source materials */ +/* Licensed Internal Code Source Materials */ +/* IBM HostBoot Licensed Internal Code */ +/* */ +/* The source code for this program is not published or otherwise */ +/* divested of its trade secrets, irrespective of what has been */ +/* deposited with the U.S. Copyright Office. */ +/* */ +/* Origin: 30 */ +/* */ +/* IBM_PROLOG_END_TAG */ + +/** + * @file targeting/targplatutil.C + * + * @brief Provides implementation for general platform specific utilities + * to support core functions + */ + +//****************************************************************************** +// Includes +//****************************************************************************** + +// STD +#include <stdlib.h> + +// TARG +#include <targeting/targplatutil.H> +#include <targeting/common/predicates/predicates.H> +#include <errl/errlmanager.H> + +namespace TARGETING +{ + +namespace UTIL +{ + +#define TARG_NAMESPACE "TARGETING::UTIL" +#define TARG_CLASS "" + +//****************************************************************************** +// createTracingError +//****************************************************************************** + +void createTracingError( + const uint8_t i_modId, + const uint16_t i_reasonCode, + const uint32_t i_userData1, + const uint32_t i_userData2, + const uint32_t i_userData3, + const uint32_t i_userData4, + errlHndl_t& io_pError) +{ + errlHndl_t pNewError = new ERRORLOG::ErrlEntry( + ERRORLOG::ERRL_SEV_INFORMATIONAL, + i_modId, + i_reasonCode, + static_cast<uint64_t>(i_userData1) << 32 + | (i_userData2 & (0xFFFFFFFF)), + static_cast<uint64_t>(i_userData3) << 32 + | (i_userData4 & (0xFFFFFFFF))); + if(io_pError != NULL) + { + // Tie logs together; existing log primary, new log as secondary + pNewError->plid(io_pError->plid()); + errlCommit(pNewError,TARG_COMP_ID); + } + else + { + io_pError = pNewError; + pNewError = NULL; + } + + return; +} + +void getMasterNodeTarget(Target*& o_masterNodeTarget) +{ + Target* masterNodeTarget = NULL; + PredicateCTM nodeFilter(CLASS_ENC, TYPE_NODE); + TargetRangeFilter localBlueprintNodes( + targetService().begin(), + targetService().end(), + &nodeFilter); + if(localBlueprintNodes) + { + masterNodeTarget = *localBlueprintNodes; + } + + o_masterNodeTarget = masterNodeTarget; +} + +#undef TARG_NAMESPACE +#undef TARG_CLASS + +} // End namespace TARGETING::UTIL + +} // End namespace TARGETING + diff --git a/src/usr/targeting/xmltohb/makefile b/src/usr/targeting/xmltohb/makefile index 8ce66479b..565f5c704 100644 --- a/src/usr/targeting/xmltohb/makefile +++ b/src/usr/targeting/xmltohb/makefile @@ -121,12 +121,12 @@ ${GENDIR}/${XMLTOHB_MERGED_COMMON_TARGET_SOURCES}: \ # generic XML is created from the generic sources only ${GENDIR}/${XMLTOHB_GENERIC_XML}: \ ${XMLTOHB_MERGE_SCRIPT} ${XMLTOHB_GENERIC_SOURCES} - $< $^ > $@ + $< $(wordlist 2,$(words $^),$^) > $@ # merge all FAPI attribute files into one ${GENDIR}/${XMLTOHB_FAPI_XML}: ${XMLTOHB_MERGE_SCRIPT} \ ${XMLTOHB_FAPIATTR_SOURCES} - $< $^ > $@ + $< $(wordlist 2,$(words $^),$^) > $@ # create the header files, only needs generic xml $(call GENTARGET,$(XMLTOHB_TARGETS)) : $(XMLTOHB_RAN_INDICATION) |