summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorZane Shelley <zshelle@us.ibm.com>2018-03-29 21:20:01 -0500
committerZane C. Shelley <zshelle@us.ibm.com>2018-04-10 11:08:00 -0400
commit58b9dd72866a2eed96e74b92b732443b59376571 (patch)
tree1dc26b8ebc4a7f0fe345f98d482bea1d0f3a6850
parent1e784c03824d66dd76ee5effe16b55782c703599 (diff)
downloadtalos-hostboot-58b9dd72866a2eed96e74b92b732443b59376571.tar.gz
talos-hostboot-58b9dd72866a2eed96e74b92b732443b59376571.zip
PRD: support getMemAddrRange() for MBA targets and DIMMs
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>
-rw-r--r--src/usr/diag/prdf/common/plat/prdfPlatServices_common.C26
-rwxr-xr-xsrc/usr/diag/prdf/common/plat/prdfPlatServices_common.H12
-rw-r--r--src/usr/diag/prdf/plat/mem/prdfMemDynDealloc.C160
-rw-r--r--src/usr/diag/prdf/plat/prdfPlatServices.C70
-rw-r--r--src/usr/diag/prdf/plat/prdfPlatServices.H35
5 files changed, 144 insertions, 159 deletions
diff --git a/src/usr/diag/prdf/common/plat/prdfPlatServices_common.C b/src/usr/diag/prdf/common/plat/prdfPlatServices_common.C
index 30cc2568b..bc1955e11 100644
--- a/src/usr/diag/prdf/common/plat/prdfPlatServices_common.C
+++ b/src/usr/diag/prdf/common/plat/prdfPlatServices_common.C
@@ -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 )
diff --git a/src/usr/diag/prdf/common/plat/prdfPlatServices_common.H b/src/usr/diag/prdf/common/plat/prdfPlatServices_common.H
index a62325226..ed3e3e324 100755
--- a/src/usr/diag/prdf/common/plat/prdfPlatServices_common.H
+++ b/src/usr/diag/prdf/common/plat/prdfPlatServices_common.H
@@ -294,18 +294,6 @@ int32_t mssSetSteerMux( TARGETING::TargetHandle_t i_mba, const CenRank & i_rank,
*/
/**
- * @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.
* @param i_rank Rank.
diff --git a/src/usr/diag/prdf/plat/mem/prdfMemDynDealloc.C b/src/usr/diag/prdf/plat/mem/prdfMemDynDealloc.C
index e82f6c0a6..b7c76874c 100644
--- a/src/usr/diag/prdf/plat/mem/prdfMemDynDealloc.C
+++ b/src/usr/diag/prdf/plat/mem/prdfMemDynDealloc.C
@@ -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 );
@@ -455,53 +461,36 @@ 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 );
@@ -509,86 +498,65 @@ int32_t port( ExtensibleChip * i_chip )
} 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
}
diff --git a/src/usr/diag/prdf/plat/prdfPlatServices.C b/src/usr/diag/prdf/plat/prdfPlatServices.C
index e558c0c7f..ed81bd376 100644
--- a/src/usr/diag/prdf/plat/prdfPlatServices.C
+++ b/src/usr/diag/prdf/plat/prdfPlatServices.C
@@ -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
//##############################################################################
diff --git a/src/usr/diag/prdf/plat/prdfPlatServices.H b/src/usr/diag/prdf/plat/prdfPlatServices.H
index 370bcbad0..0cf7119e8 100644
--- a/src/usr/diag/prdf/plat/prdfPlatServices.H
+++ b/src/usr/diag/prdf/plat/prdfPlatServices.H
@@ -119,32 +119,16 @@ enum AddrRangeType
* address range. The MCBIST HW logic tolerates this unlike the MBA HW
* logic. Functions like Dynamic Memory Deallocation may need to adjust
* the actual address based on the actual HW config.
- * @param i_chip An MCA.
- * @param i_rank The target rank.
- * @param o_startAddr The returned start address.
- * @param o_endAddr The returned end address.
- * @param i_rangeType See enum AddrRangeType.
- * @return Non-SUCCESS if internal function fails, SUCCESS otherwise.
- */
-template<TARGETING::TYPE T>
-uint32_t getMemAddrRange( ExtensibleChip * i_chip, const MemRank & i_rank,
- mss::mcbist::address & o_startAddr,
- mss::mcbist::address & o_endAddr,
- AddrRangeType i_rangeType );
-
-/**
- * @brief Returns the start and end address of the given rank.
- * @param i_chip An MBA.
+ * @param i_chip An MCA or MBA.
* @param i_rank The target rank.
* @param o_startAddr The returned start address.
* @param o_endAddr The returned end address.
* @param i_rangeType See enum AddrRangeType.
* @return Non-SUCCESS if internal function fails, SUCCESS otherwise.
*/
-template<TARGETING::TYPE T>
+template<TARGETING::TYPE TT, typename VT>
uint32_t getMemAddrRange( ExtensibleChip * i_chip, const MemRank & i_rank,
- fapi2::buffer<uint64_t> & o_startAddr,
- fapi2::buffer<uint64_t> & o_endAddr,
+ VT & o_startAddr, VT & o_endAddr,
AddrRangeType i_rangeType );
/**
@@ -155,16 +139,17 @@ uint32_t getMemAddrRange( ExtensibleChip * i_chip, const MemRank & i_rank,
* logic. Functions like Dynamic Memory Deallocation may need to adjust
* the actual address based on the actual HW config.
* @param i_chip An MCA or MBA.
- * @param i_rank The target rank.
* @param o_startAddr The returned start address.
* @param o_endAddr The returned end address.
- * @param i_rangeType See enum AddrRangeType.
+ * @param i_dimmSlct When used, this function will only return the address
+ * range for the target DIMM select. Otherwise, the default
+ * is to return the address range for all DIMM selects.
* @return Non-SUCCESS if internal function fails, SUCCESS otherwise.
*/
-template<TARGETING::TYPE T>
-uint32_t getMemAddrRange( ExtensibleChip * i_chip, const MemRank & i_rank,
- MemAddr & o_startAddr, MemAddr & o_endAddr,
- AddrRangeType i_rangeType );
+template<TARGETING::TYPE TT, typename VT>
+uint32_t getMemAddrRange( ExtensibleChip * i_chip,
+ VT & o_startAddr, VT & o_endAddr,
+ uint8_t i_dimmSlct = MAX_DIMM_PER_PORT );
//##############################################################################
//## Nimbus/Centaur Maintenance Command wrappers
OpenPOWER on IntegriCloud