Skip to content

Commit

Permalink
Support multiple nodes in HBRT - Support Multiple Nodes in TargetService
Browse files Browse the repository at this point in the history
Change to call the TargetService class initialization function with the correct
maximum number of nodes rather than always defaulting to 1.  Provide support to
get first target iterator for a specific node.  Update AttrRP::translateAddr
functions to handle nodes.

Change-Id: Ia3496c2f4daf0b78999bde35565f4541fedb0b4d
RTC: 186869
Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/53190
Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com>
Tested-by: Jenkins OP Build CI <op-jenkins+hostboot@us.ibm.com>
Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com>
Tested-by: Jenkins OP HW <op-hw-jenkins+hostboot@us.ibm.com>
Reviewed-by: Prachi Gupta <pragupta@us.ibm.com>
Reviewed-by: Richard J. Knight <rjknight@us.ibm.com>
Reviewed-by: Daniel M. Crowell <dcrowell@us.ibm.com>
  • Loading branch information
mgloff authored and dcrowell77 committed Mar 5, 2018
1 parent 4823581 commit 40c3350
Show file tree
Hide file tree
Showing 6 changed files with 254 additions and 58 deletions.
22 changes: 18 additions & 4 deletions src/include/usr/targeting/attrrp.H
Original file line number Diff line number Diff line change
Expand Up @@ -170,14 +170,28 @@ class AttrRP
*/
void* getBaseAddress(const NODE_ID i_nodeId);

/**
* @brief Returns Node Id of the Target handle passed
*
* @param[in] i_pTarget
* Non-NULL Target handle for which node ID is required.
* @param[out] o_nodeId
* Node ID of the Target Handle requested. If Target not found
* the invalid node will be return in here.
*
* @return void
*/
void getNodeId(const Target* i_pTarget,
NODE_ID& o_nodeId) const;

/**
* @brief Translates given address, according to the resource
* provider's translation algorithm
*
* @param[in] i_pAddress
* Address to translate
*
* @param[in] i_pUnused
* @param[in] i_pTarget
* Node target used by common code, unused in Hostboot
*
* @return void* Returns the translated address. Common attribute
Expand All @@ -189,7 +203,7 @@ class AttrRP
*/
void* translateAddr(
void* i_pAddress,
const Target* i_pUnused)
const Target* i_pTarget)
#ifndef __HOSTBOOT_RUNTIME
{
return i_pAddress;
Expand All @@ -205,7 +219,7 @@ class AttrRP
* @param[in] i_pAddress
* Address to translate
*
* @param[in] i_unused
* @param[in] i_nodeId
* Node ID used by common code, unused in Hostboot
*
* @return void* Returns the translated address. Common attribute
Expand All @@ -217,7 +231,7 @@ class AttrRP
*/
void* translateAddr(
void* i_pAddress,
const TARGETING::NODE_ID i_unused)
const TARGETING::NODE_ID i_nodeId)
#ifndef __HOSTBOOT_RUNTIME
{
return i_pAddress;
Expand Down
34 changes: 33 additions & 1 deletion src/include/usr/targeting/common/targetservice.H
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,18 @@ class TargetService
*/
iterator begin();

#ifdef __HOSTBOOT_RUNTIME
/**
* @brief Return iterator which points to first target service target
* (or end() if none) for a specific node
*
* @param[in] i_nodeId, node Id
*
* @return Iterator pointing to first target service target for node
*/
iterator begin(NODE_ID i_nodeId);
#endif

/**
* @brief Return rawiterator which points to first target service
* target (or end() if none)
Expand Down Expand Up @@ -801,7 +813,7 @@ class TargetService
* @brief Returns the first Target from the first initialized node
* from the pool of targets.
*
* param[out] o_firstTargetPtr First Target handle
* @param[out] o_firstTargetPtr First Target handle
*
* @pre Target service must be initialized
*
Expand All @@ -812,6 +824,26 @@ class TargetService
*/
void _getFirstTargetForIterators (Target*& o_firstTargetPtr) const;

#ifdef __HOSTBOOT_RUNTIME
/**
* @brief Returns the first Target from the node's pool of targets if
* node is initialized.
*
* @param[out] o_firstTargetPtr First Target handle or nullptr
*
* @param[in] i_nodeId, node Id
*
* @pre Target service must be initialized
*
* @post Target Service returns the first Target from the node if node
* is initialized.
*
* @returns void
*/
void _getFirstTargetForIterators (Target*& o_firstTargetPtr,
NODE_ID i_nodeId) const;
#endif

/**
* @brief Configures the pool of targets
*
Expand Down
64 changes: 64 additions & 0 deletions src/usr/targeting/common/targetservice.C
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,13 @@ void TargetService::init(const size_t i_maxNodes)

l_nodeInfo.initialized = true;
}

Target* l_pFirstTarget = &(*(l_nodeInfo.targets))[0];
TARG_INF("TargetService::init: Pushing info for node %d with first "
"target huid 0x%.8x and %d total targets",
l_nodeInfo.nodeId,
get_huid(l_pFirstTarget),
l_nodeInfo.maxTargets);
iv_nodeInfo.push_back(l_nodeInfo);
}

Expand Down Expand Up @@ -256,6 +263,43 @@ void TargetService::_getFirstTargetForIterators(Target*& o_firstTargetPtr) const
#undef TARG_FN
}

#ifdef __HOSTBOOT_RUNTIME
//******************************************************************************
// TargetService:: _getFirstTargetForIterators
//******************************************************************************

void TargetService::_getFirstTargetForIterators(Target*& o_firstTargetPtr,
NODE_ID i_nodeId) const
{
#define TARG_FN "_getFirstTargetForIterators()"
TARG_ASSERT(iv_initialized, TARG_ERR_LOC
"USAGE: TargetService not initialized");

/* This will come inside for initialized node only.. Just for safety we
* are checking for maxTargets & whether it is initialized or not */
if( (i_nodeId < MAX_NODE_ID) &&
(iv_nodeInfo[i_nodeId].initialized == true) &&
(iv_nodeInfo[i_nodeId].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[i_nodeId].targets))[0];

TARG_ASSERT(o_firstTargetPtr != NULL, TARG_ERR_LOC
"FATAL: Could not find any targets");
}
else
{
o_firstTargetPtr = nullptr;
}

#undef TARG_FN
}
#endif

//******************************************************************************
// TargetService::begin (non-const version)
//******************************************************************************
Expand All @@ -274,6 +318,26 @@ TargetService::iterator TargetService::begin()
#undef TARG_FN
}

#ifdef __HOSTBOOT_RUNTIME
//******************************************************************************
// TargetService::begin (non-const version)
//******************************************************************************

TargetService::iterator TargetService::begin(NODE_ID i_nodeId)
{
#define TARG_FN "begin()"
Target* l_pFirstTarget = nullptr;

TARG_ASSERT(iv_initialized, TARG_ERR_LOC
"USAGE: TargetService not initialized");

_getFirstTargetForIterators(l_pFirstTarget, i_nodeId);
return iterator(l_pFirstTarget);

#undef TARG_FN
}
#endif

//******************************************************************************
// TargetService::raw_begin (non-const version)
//******************************************************************************
Expand Down
87 changes: 75 additions & 12 deletions src/usr/targeting/runtime/attrrp_rt.C
Original file line number Diff line number Diff line change
Expand Up @@ -488,33 +488,96 @@ namespace TARGETING
#undef TARG_FN
}

void AttrRP::getNodeId(const Target* i_pTarget,
NODE_ID& o_nodeId) const
{
#define TARG_FN "getNodeId"

bool l_found = false;

// Initialize with invalid
o_nodeId = INVALID_NODE_ID;

//find the node to which this target belongs
for(uint8_t i=0; i<INVALID_NODE_ID; ++i)
{
for(uint32_t j=0; j<iv_nodeContainer[i].sectionCount; ++j)
{
if( iv_nodeContainer[i].pSections[j].type ==
SECTION_TYPE_PNOR_RO)
{
// This expects the pTarget to be always in range and !NULL.
// If any invalid target is passed (which is still within the
// RO Section scope) then behaviour is undefined.
if( (i_pTarget >= iv_nodeContainer[i].pTargetMap) &&
(i_pTarget < reinterpret_cast<Target*>((
reinterpret_cast<uint8_t*>(
iv_nodeContainer[i].pTargetMap) +
iv_nodeContainer[i].pSections[j].size))) )
{
l_found = true;
o_nodeId = i;
break;
}
}
}
if(l_found)
{
break;
}
}
#undef TARG_FN
}

void* AttrRP::translateAddr(void* i_pAddress,
const Target* i_pUnused)
const Target* i_pTarget)
{
void* l_address = i_pAddress;
#define TARG_FN "translateAddr(..., Target*)"
// TARG_ENTER(); // Disabled due to number of traces created

NODE_ID l_nodeId = NODE0;

for (size_t i = 0; i < iv_sectionCount; ++i)
if(i_pTarget != NULL)
{
if ((iv_sections[i].vmmAddress + iv_sections[i].size) >=
getNodeId(i_pTarget, l_nodeId);
}

void* l_address = translateAddr(i_pAddress, l_nodeId);

// TARG_EXIT(); // Disabled due to number of traces created
#undef TARG_FN

return l_address;
}

void* AttrRP::translateAddr(void* i_pAddress,
const TARGETING::NODE_ID i_nodeId)
{
#define TARG_FN "translateAddr(..., NODE_ID)"
// TARG_ENTER(); // Disabled due to number of traces created

void* l_address = NULL;

for (size_t i = 0; i < iv_nodeContainer[i_nodeId].sectionCount; ++i)
{
if ((iv_nodeContainer[i_nodeId].pSections[i].vmmAddress +
iv_nodeContainer[i_nodeId].pSections[i].size) >=
reinterpret_cast<uint64_t>(i_pAddress))
{
l_address = reinterpret_cast<void*>(
iv_sections[i].pnorAddress +
iv_nodeContainer[i_nodeId].pSections[i].pnorAddress +
reinterpret_cast<uint64_t>(i_pAddress) -
iv_sections[i].vmmAddress);
iv_nodeContainer[i_nodeId].pSections[i].vmmAddress);
break;
}
}

TRACDCOMP(g_trac_targeting, "Translated 0x%p to 0x%p",
i_pAddress, l_address);

return l_address;
}
// TARG_EXIT(); // Disabled due to number of traces created
#undef TARG_FN

void* AttrRP::translateAddr(void* i_pAddress,
const TARGETING::NODE_ID i_unused)
{
return translateAddr(i_pAddress, static_cast<Target*>(NULL));
return l_address;
}
}
35 changes: 26 additions & 9 deletions src/usr/targeting/runtime/rt_targeting.C
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@
#include <util/memoize.H>
#include <util/runtime/util_rt.H>
#include <util/utillidmgr.H>
#include <sys/internode.h>


using namespace TARGETING;

Expand Down Expand Up @@ -123,17 +125,32 @@ errlHndl_t _getHbTarget(
TARGETING::TargetHandle_t pTarget = NULL;
if(i_rtTargetId != RUNTIME::HBRT_HYP_ID_UNKNOWN)
{
for (TARGETING::TargetIterator pIt =
TARGETING::targetService().begin();
pIt != TARGETING::targetService().end();
++pIt)
uint8_t l_maxNodeId =
TARGETING::targetService().getNumInitializedNodes();
for(uint8_t l_nodeId=NODE0; l_nodeId<l_maxNodeId; ++l_nodeId)
{
auto rtTargetId = RUNTIME::HBRT_HYP_ID_UNKNOWN;
if( ((*pIt)->tryGetAttr<
TARGETING::ATTR_HBRT_HYP_ID>(rtTargetId))
&& (rtTargetId == i_rtTargetId))
TRACFCOMP( g_trac_targeting, "Node %d beginning target %p",
l_nodeId,
*(TARGETING::targetService().begin(l_nodeId)));

for (TARGETING::TargetIterator pIt =
TARGETING::targetService().begin(l_nodeId);
pIt != TARGETING::targetService().end();
++pIt)
{
auto rtTargetId = RUNTIME::HBRT_HYP_ID_UNKNOWN;
if( (*pIt != nullptr)
&& ((*pIt)->tryGetAttr<
TARGETING::ATTR_HBRT_HYP_ID>(rtTargetId))
&& (rtTargetId == i_rtTargetId))
{
pTarget = (*pIt);
break;
}
}

if(pTarget)
{
pTarget = (*pIt);
break;
}
}
Expand Down

0 comments on commit 40c3350

Please sign in to comment.