Skip to content

Commit

Permalink
PRD: support getMemAddrRange() for MBA targets and DIMMs
Browse files Browse the repository at this point in the history
Change-Id: I899e5912cf69a25b7d67eaddfd38c6239bc4be53
RTC: 190363
Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/56500
Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com>
Reviewed-by: Benjamin J. Weisenbeck <bweisenb@us.ibm.com>
Reviewed-by: Caleb N. Palmer <cnpalmer@us.ibm.com>
Reviewed-by: Zane C. Shelley <zshelle@us.ibm.com>
Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/56889
CI-Ready: Zane C. Shelley <zshelle@us.ibm.com>
Tested-by: Jenkins OP Build CI <op-jenkins+hostboot@us.ibm.com>
Tested-by: Jenkins OP HW <op-hw-jenkins+hostboot@us.ibm.com>
Tested-by: Zane C. Shelley <zshelle@us.ibm.com>
  • Loading branch information
zane131 committed Apr 10, 2018
1 parent 1e784c0 commit 58b9dd7
Show file tree
Hide file tree
Showing 5 changed files with 144 additions and 159 deletions.
26 changes: 0 additions & 26 deletions src/usr/diag/prdf/common/plat/prdfPlatServices_common.C
Original file line number Diff line number Diff line change
Expand Up @@ -574,32 +574,6 @@ int32_t mssSetSteerMux( TargetHandle_t i_mba, const CenRank & i_rank,

//------------------------------------------------------------------------------

/* TODO RTC 157888
int32_t getMemAddrRange( TargetHandle_t i_mba, CenAddr & o_startAddr,
CenAddr & o_endAddr )
{
#define PRDF_FUNC "[PlatServices::getMemAddrRange] "
ecmdDataBufferBase startAddr(64), endAddr(64);
int32_t o_rc = getMemAddrRange( i_mba, MSS_ALL_RANKS, startAddr, endAddr );
if ( SUCCESS != o_rc )
{
PRDF_ERR( PRDF_FUNC "Failed: i_mba=0x%08x", getHuid(i_mba) );
}
else
{
o_startAddr = CenAddr::fromMaintStartAddr( startAddr.getDoubleWord(0) );
o_endAddr = CenAddr::fromMaintEndAddr( endAddr.getDoubleWord(0) );
}
return o_rc;
#undef PRDF_FUNC
}
*/

//------------------------------------------------------------------------------

/* TODO RTC
int32_t getDimmSpareConfig( TargetHandle_t i_mba, CenRank i_rank,
uint8_t i_ps, uint8_t & o_spareConfig )
Expand Down
12 changes: 0 additions & 12 deletions src/usr/diag/prdf/common/plat/prdfPlatServices_common.H
Original file line number Diff line number Diff line change
Expand Up @@ -293,18 +293,6 @@ int32_t mssSetSteerMux( TARGETING::TargetHandle_t i_mba, const CenRank & i_rank,
const CenSymbol & i_symbol, bool i_x4EccSpare );
*/

/**
* @brief Returns the start and end maintenance address of the given MBA.
* @param i_mba Target MBA.
* @param o_startAddr The return start address.
* @param o_endAddr The return end address.
* @return Non-SUCCESS in internal function fails, SUCCESS otherwise.
*/
/* TODO RTC 157888
int32_t getMemAddrRange( TARGETING::TargetHandle_t i_mba, CenAddr & o_startAddr,
CenAddr & o_endAddr );
*/

/**
* @brief Get spare DRAM information on a DIMM.
* @param i_mba MBA target.
Expand Down
160 changes: 64 additions & 96 deletions src/usr/diag/prdf/plat/mem/prdfMemDynDealloc.C
Original file line number Diff line number Diff line change
Expand Up @@ -416,37 +416,43 @@ int32_t rank( ExtensibleChip * i_chip, MemRank i_rank )
#define PRDF_FUNC "[MemDealloc::rank] "

int32_t o_rc = SUCCESS;

do
{
if ( !isEnabled() ) break; // nothing to do

// Get the address range of i_rank.
MemAddr startAddr, endAddr;
o_rc = getMemAddrRange<T>( i_chip, i_rank, startAddr, endAddr,
SLAVE_RANK );
if ( SUCCESS != o_rc )
{
PRDF_ERR( PRDF_FUNC "getMemAddrRange() Failed. HUID:0x%08X",
i_chip->GetId() );
PRDF_ERR( PRDF_FUNC "getMemAddrRange(0x%08x,0x%02x) failed",
i_chip->getHuid(), i_rank.getKey() );
break;
}

// Get the system addresses
// Get the system addresses.
uint64_t ssAddr = 0;
uint64_t seAddr = 0;
o_rc = getSystemAddr<T>( i_chip, startAddr, ssAddr);
o_rc |= getSystemAddr<T>( i_chip, endAddr, seAddr );
o_rc = getSystemAddr<T>( i_chip, startAddr, ssAddr );
o_rc |= getSystemAddr<T>( i_chip, endAddr, seAddr );
if ( SUCCESS != o_rc )
{
PRDF_ERR( PRDF_FUNC "getSystemAddr() failed. HUID:0x%08X",
i_chip->GetId() );
PRDF_ERR( PRDF_FUNC "getSystemAddr(0x%08x) failed",
i_chip->getHuid() );
break;
}
// Send the address range to HV

// Send the address range to the hypervisor.
sendDynMemDeallocRequest( ssAddr, seAddr );
PRDF_TRAC( PRDF_FUNC "Rank dealloc for Start Addr: 0x%016llx "
"End Addr: 0x%016llx", ssAddr, seAddr );

} while( 0 );
} while (0);

return o_rc;

#undef PRDF_FUNC
}
template int32_t rank<TYPE_MCA>( ExtensibleChip * i_chip, MemRank i_rank );
Expand All @@ -455,140 +461,102 @@ template<TYPE T>
int32_t port( ExtensibleChip * i_chip )
{
#define PRDF_FUNC "[MemDealloc::port] "

int32_t o_rc = SUCCESS;

do
{
if ( !isEnabled() ) break; // nothing to do

TargetHandle_t tgt = i_chip->GetChipHandle();
// Get the address range of i_chip.
MemAddr startAddr, endAddr;
o_rc = getMemAddrRange<T>( i_chip, startAddr, endAddr );
if ( SUCCESS != o_rc )
{
PRDF_ERR( PRDF_FUNC "getMemAddrRange(0x%08x) failed",
i_chip->getHuid() );
break;
}

// Find the largest address range
uint64_t smallestAddr = 0xffffffffffffffffll;
uint64_t largestAddr = 0;
// Get the system addresses.
uint64_t ssAddr = 0;
uint64_t seAddr = 0;
MemAddr startAddr, endAddr;
std::vector<MemRank> masterRanks;

// Get Master ranks
getMasterRanks<T>( tgt, masterRanks);

// Iterate all ranks to get start and end address.
for ( std::vector<MemRank>::iterator it = masterRanks.begin();
it != masterRanks.end(); it++ )
o_rc = getSystemAddr<T>( i_chip, startAddr, ssAddr );
o_rc |= getSystemAddr<T>( i_chip, endAddr, seAddr );
if ( SUCCESS != o_rc )
{
o_rc = getMemAddrRange<T>( i_chip, *it, startAddr, endAddr,
MASTER_RANK );
if ( SUCCESS != o_rc )
{
PRDF_ERR( PRDF_FUNC "getMemAddrRange() Failed. HUID:0x%08X",
i_chip->GetId() );
break;
}

// Get the system addresses
o_rc = getSystemAddr<T>( i_chip, startAddr, ssAddr);
o_rc |= getSystemAddr<T>( i_chip, endAddr, seAddr );
if ( SUCCESS != o_rc )
{
PRDF_ERR( PRDF_FUNC "getSystemAddr() failed. HUID:0x%08X",
i_chip->GetId() );
break;
}
if ( ssAddr < smallestAddr ) smallestAddr = ssAddr;
if ( seAddr > largestAddr ) largestAddr = seAddr;
PRDF_ERR( PRDF_FUNC "getSystemAddr(0x%08x) failed",
i_chip->getHuid() );
break;
}
if( SUCCESS != o_rc ) break;

// Send the address range to PHYP
// Send the address range to the hypervisor.
sendDynMemDeallocRequest( ssAddr, seAddr );
PRDF_TRAC( PRDF_FUNC "Port dealloc for Start Addr: 0x%016llx "
"End Addr: 0x%016llx", ssAddr, seAddr );

} while (0);

return o_rc;

#undef PRDF_FUNC
}
template int32_t port<TYPE_MCA>( ExtensibleChip * i_chip );

template <TYPE T>
int32_t dimmSlct( TargetHandle_t i_dimm )
int32_t dimmSlct( TargetHandle_t i_dimm )
{
#define PRDF_FUNC "[MemDealloc::dimmSlct] "

int32_t o_rc = SUCCESS;

do
{
if ( !isEnabled() ) break; // nothing to do

TargetHandle_t tgt = getConnectedParent( i_dimm, T );

if ( tgt == NULL )
// Get the MCA, MBA, etc. connected to this DIMM.
TargetHandle_t trgt = getConnectedParent( i_dimm, T );
ExtensibleChip * chip = (ExtensibleChip *)systemPtr->GetChip( trgt );
if ( nullptr == chip )
{
PRDF_ERR( PRDF_FUNC "Failed to get parent for dimm 0x%08X",
getHuid( i_dimm ) );
PRDF_ERR( PRDF_FUNC "No chip connected to DIMM" );
o_rc = FAIL; break;
}

ExtensibleChip * chip = (ExtensibleChip *)systemPtr->GetChip( tgt );
if ( NULL == chip )
{
PRDF_ERR( PRDF_FUNC "No MBA/MCA chip behind DIMM" );
o_rc = FAIL; break;
}
// Find the largest address range
uint64_t smallestAddr = 0xffffffffffffffffll;
uint64_t largestAddr = 0;
MemAddr startAddr, endAddr;
std::vector<MemRank> masterRanks;
// Get the DIMM select.
uint8_t dimmSlct = getDimmSlct<T>( i_dimm );

getMasterRanks<T>( tgt, masterRanks, dimmSlct );

// Iterate all ranks to get start and end address.
for ( std::vector<MemRank>::iterator it = masterRanks.begin();
it != masterRanks.end(); it++ )
// Get the address range of i_dimm.
MemAddr startAddr, endAddr;
o_rc = getMemAddrRange<T>( chip, startAddr, endAddr, dimmSlct );
if ( SUCCESS != o_rc )
{
o_rc = getMemAddrRange<T>( chip, *it, startAddr, endAddr,
MASTER_RANK );
if ( SUCCESS != o_rc )
{
PRDF_ERR( PRDF_FUNC "getMemAddrRange() Failed. HUID:0x%08X",
chip->GetId() );
break;
}
PRDF_ERR( PRDF_FUNC "getMemAddrRange(0x%08x,%d) failed",
chip->getHuid(), dimmSlct );
break;
}

// Get the system addresses
uint64_t ssAddr = 0;
uint64_t seAddr = 0;
o_rc = getSystemAddr<T>( chip, startAddr, ssAddr);
o_rc |= getSystemAddr<T>( chip, endAddr, seAddr );
if ( SUCCESS != o_rc )
{
PRDF_ERR( PRDF_FUNC "getSystemAddr() failed. HUID:0x%08X",
chip->GetId() );
break;
}
if ( ssAddr < smallestAddr ) smallestAddr = ssAddr;
if ( seAddr > largestAddr ) largestAddr = seAddr;
// Get the system addresses.
uint64_t ssAddr = 0;
uint64_t seAddr = 0;
o_rc = getSystemAddr<T>( chip, startAddr, ssAddr );
o_rc |= getSystemAddr<T>( chip, endAddr, seAddr );
if ( SUCCESS != o_rc )
{
PRDF_ERR( PRDF_FUNC "getSystemAddr(0x%08x) failed",
chip->getHuid() );
break;
}
if( SUCCESS != o_rc ) break;

// Send the address range to PHYP
sendDynMemDeallocRequest( smallestAddr, largestAddr );
// Send the address range to the hypervisor.
sendDynMemDeallocRequest( ssAddr, seAddr );
PRDF_TRAC( PRDF_FUNC "DIMM Slct dealloc for Start Addr: 0x%016llx "
"End Addr: 0x%016llx", smallestAddr, largestAddr );
"End Addr: 0x%016llx", ssAddr, seAddr );

} while (0);

if( FAIL == o_rc )
{
PRDF_ERR( PRDF_FUNC "failed. DIMM:0x%08X", getHuid( i_dimm ) );
}

return o_rc;

#undef PRDF_FUNC
}

Expand Down
70 changes: 70 additions & 0 deletions src/usr/diag/prdf/plat/prdfPlatServices.C
Original file line number Diff line number Diff line change
Expand Up @@ -423,6 +423,76 @@ uint32_t getMemAddrRange<TYPE_MBA>( ExtensibleChip * i_chip,
return o_rc;
}

//------------------------------------------------------------------------------

template<TARGETING::TYPE TT, typename VT>
uint32_t getMemAddrRange( ExtensibleChip * i_chip, VT & o_startAddr,
VT & o_endAddr, uint8_t i_dimmSlct )
{
#define PRDF_FUNC "[PlatServices::__getMemAddrRange] "

uint32_t o_rc = SUCCESS;

do
{
// Get the rank list.
std::vector<MemRank> rankList;
getMasterRanks<TT>( i_chip->getTrgt(), rankList, i_dimmSlct );
if ( rankList.empty() )
{
PRDF_ERR( PRDF_FUNC "i_chip=0x%08x configured with no ranks",
i_chip->getHuid() );
o_rc = FAIL;
break;
}

// rankList is guaranteed to be sorted. So get the first and last rank.
MemRank firstRank = rankList.front();
MemRank lastRank = rankList.back();

// Get the address range of the first rank.
o_rc = getMemAddrRange<TT>( i_chip, firstRank, o_startAddr, o_endAddr,
MASTER_RANK );
if ( SUCCESS != o_rc ) break;

// Check if there is only one rank configured.
if ( firstRank == lastRank ) break;

// Get the end address of the last rank.
VT junk;
o_rc = getMemAddrRange<TT>( i_chip, lastRank, junk, o_endAddr,
MASTER_RANK );
if ( SUCCESS != o_rc ) break;

} while (0);

return o_rc;

#undef PRDF_FUNC
}

template
uint32_t getMemAddrRange<TYPE_MCA>( ExtensibleChip * i_chip,
mss::mcbist::address & o_startAddr,
mss::mcbist::address & o_endAddr,
uint8_t i_dimmSlct );

template
uint32_t getMemAddrRange<TYPE_MBA>( ExtensibleChip * i_chip,
fapi2::buffer<uint64_t> & o_startAddr,
fapi2::buffer<uint64_t> & o_endAddr,
uint8_t i_dimmSlct );

template
uint32_t getMemAddrRange<TYPE_MBA>( ExtensibleChip * i_chip,
MemAddr & o_startAddr, MemAddr & o_endAddr,
uint8_t i_dimmSlct );

template
uint32_t getMemAddrRange<TYPE_MCA>( ExtensibleChip * i_chip,
MemAddr & o_startAddr, MemAddr & o_endAddr,
uint8_t i_dimmSlct );

//##############################################################################
//## Nimbus Maintenance Command wrappers
//##############################################################################
Expand Down

0 comments on commit 58b9dd7

Please sign in to comment.