Skip to content

Commit

Permalink
PRD: Increment addr to next row for VCM row repair
Browse files Browse the repository at this point in the history
Change-Id: I3ffb09f8bf1af96587762dbeba665942a13cdcbc
CQ: SW449443
Reviewed-on: http://rchgit01.rchland.ibm.com/gerrit1/67860
Reviewed-by: Caleb N. Palmer <cnpalmer@us.ibm.com>
Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com>
Reviewed-by: Zane C. Shelley <zshelle@us.ibm.com>
Reviewed-on: http://rchgit01.rchland.ibm.com/gerrit1/68108
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: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com>
  • Loading branch information
cnpalmer authored and zane131 committed Oct 30, 2018
1 parent 451a26b commit 414037d
Show file tree
Hide file tree
Showing 14 changed files with 296 additions and 55 deletions.
73 changes: 67 additions & 6 deletions src/usr/diag/prdf/common/plat/mem/prdfMemAddress.C
Original file line number Diff line number Diff line change
Expand Up @@ -106,12 +106,14 @@ MemAddr MemAddr::fromMaintAddr<TYPE_MBA>( uint64_t i_addr )
template<>
uint64_t MemAddr::toMaintAddr<TYPE_MBA>() const
{
return ( ((uint64_t) iv_rnk.getMaster() << 60) | // 1: 3
((uint64_t) iv_rnk.getSlave() << 57) | // 4: 6
((uint64_t) iv_bnk << 53) | // 7:10
((uint64_t)(iv_row & 0x1ffff) << 36) | // 11:27
((uint64_t) iv_col << 27) | // 28:36 (37:39 tied to 0)
((uint64_t)(iv_row & 0x20000) >> 13) ); // 59
return (
((uint64_t)(iv_rnk.getMaster() & 0x7)<< 60) | // 1: 3
((uint64_t)(iv_rnk.getSlave() & 0x7)<< 57) | // 4: 6
((uint64_t)(iv_bnk & 0xf)<< 53) | // 7:10
((uint64_t)(iv_row & 0x1ffff)<< 36) | // 11:27
((uint64_t)(iv_col & 0x1ff)<< 27) | // 28:36
// 37:39 tied to 0
((uint64_t)(iv_row & 0x20000)>> 13) ); // 59
}

//------------------------------------------------------------------------------
Expand Down Expand Up @@ -326,6 +328,65 @@ uint32_t getMemMaintAddr<TYPE_MBA>( ExtensibleChip * i_chip, MemAddr & o_addr )

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

template<>
uint32_t setMemMaintAddr<TYPE_MBA>( ExtensibleChip * i_chip,
const MemAddr & i_addr )
{
#define PRDF_FUNC "[setMemMaintAddr<TYPE_MBA>] "

// Check parameters
PRDF_ASSERT( nullptr != i_chip );
PRDF_ASSERT( TYPE_MBA == i_chip->getType() );

// Write the address register
SCAN_COMM_REGISTER_CLASS * reg = i_chip->getRegister( "MBMACA" );
reg->SetBitFieldJustified( 0, 64, i_addr.toMaintAddr<TYPE_MBA>() );
uint32_t o_rc = reg->Write();
if ( SUCCESS != o_rc )
{
PRDF_ERR( PRDF_FUNC "Write() failed on MBMACA: i_chip=0x%08x",
i_chip->getHuid() );
}

return o_rc;

#undef PRDF_FUNC
}

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

template<>
uint32_t getMemMaintEndAddr<TYPE_MBA>( ExtensibleChip * i_chip,
MemAddr & o_addr )
{
#define PRDF_FUNC "[getMemMaintEndAddr<TYPE_MBA>] "

// Check parameters
PRDF_ASSERT( nullptr != i_chip );
PRDF_ASSERT( TYPE_MBA == i_chip->getType() );

// Read the address register
SCAN_COMM_REGISTER_CLASS * reg = i_chip->getRegister( "MBMEA" );
uint32_t o_rc = reg->Read();
if ( SUCCESS != o_rc )
{
PRDF_ERR( PRDF_FUNC "Read() failed on MBMEA: i_chip=0x%08x",
i_chip->getHuid() );
}
else
{
// Get the address object.
uint64_t addr = reg->GetBitFieldJustified( 0, 64 );
o_addr = MemAddr::fromMaintAddr<TYPE_MBA>( addr );
}

return o_rc;

#undef PRDF_FUNC
}

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

#ifdef __HOSTBOOT_MODULE

uint32_t getMcbistMaintPort( ExtensibleChip * i_mcbChip,
Expand Down
19 changes: 19 additions & 0 deletions src/usr/diag/prdf/common/plat/mem/prdfMemAddress.H
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,25 @@ uint32_t getMemReadAddr( ExtensibleChip * i_chip, MemAddr::ReadReg i_reg,
template<TARGETING::TYPE T>
uint32_t getMemMaintAddr( ExtensibleChip * i_chip, MemAddr & o_addr );

/**
* @brief Writes the maintenance address from hardware.
* @param i_chip An MBA chip.
* @param i_addr The address to write to hardware.
* @return Non-SUCCESS if an internal function fails, SUCCESS otherwise.
*/
template<TARGETING::TYPE T>
uint32_t setMemMaintAddr( ExtensibleChip * i_chip, const MemAddr & i_addr );

/**
* @brief Reads the maintenance command end address from hardware.
*
* @param i_chip An MBA chip.
* @param o_addr The returned end address from hardware.
* @return Non-SUCCESS if an internal function fails, SUCCESS otherwise.
*/
template<TARGETING::TYPE T>
uint32_t getMemMaintEndAddr( ExtensibleChip * i_chip, MemAddr & o_addr );

#ifdef __HOSTBOOT_MODULE

/**
Expand Down
10 changes: 9 additions & 1 deletion src/usr/diag/prdf/plat/mem/prdfMemScrubUtils.C
Original file line number Diff line number Diff line change
Expand Up @@ -587,7 +587,8 @@ uint32_t setBgScrubThresholds<TYPE_MBA>( ExtensibleChip * i_chip,
template<>
uint32_t didCmdStopOnLastAddr<TYPE_MBA>( ExtensibleChip * i_chip,
AddrRangeType i_rangeType,
bool & o_stoppedOnLastAddr )
bool & o_stoppedOnLastAddr,
bool i_rowRepair )
{
#define PRDF_FUNC "[didCmdStopOnLastAddr] "

Expand Down Expand Up @@ -618,6 +619,13 @@ uint32_t didCmdStopOnLastAddr<TYPE_MBA>( ExtensibleChip * i_chip,
break;
}

// For row repair, compare just the rank and row.
if ( i_rowRepair )
{
curAddr = MemAddr( curAddr.getRank(), 0, curAddr.getRow(), 0 );
endAddr = MemAddr( endAddr.getRank(), 0, endAddr.getRow(), 0 );
}

// Compare the addresses.
o_stoppedOnLastAddr = ( curAddr == endAddr );

Expand Down
8 changes: 7 additions & 1 deletion src/usr/diag/prdf/plat/mem/prdfMemScrubUtils.H
Original file line number Diff line number Diff line change
Expand Up @@ -179,12 +179,18 @@ uint32_t setBgScrubThresholds( ExtensibleChip * i_chip,
* @param o_stoppedOnLastAddr True, if the current maintenance command stopped
* on the last address of the given rank range.
* False, otherwise.
* @param i_rowRepair This is a special case during VCM procedures when
* row repair is enabled. It is intended to be used
* to determine if the MCE happened on the last
* row of the address range. When true, only the
* rank and the row addresses are compared.
* @return Non-SUCCESS if an internal function fails, SUCCESS otherwise.
*/
template<TARGETING::TYPE T>
uint32_t didCmdStopOnLastAddr( ExtensibleChip * i_chip,
AddrRangeType i_rangeType,
bool & o_stoppedOnLastAddr );
bool & o_stoppedOnLastAddr,
bool i_rowRepair = false );

} //end namespace PRDF

Expand Down
23 changes: 23 additions & 0 deletions src/usr/diag/prdf/plat/mem/prdfMemVcm.C
Original file line number Diff line number Diff line change
Expand Up @@ -380,6 +380,29 @@ uint32_t VcmEvent<TYPE_MBA>::handlePhaseComplete( const uint32_t & i_eccAttns,
break;
}
if ( o_done ) break;

// Row repair is enabled, we found an MCE, and we did not
// need to exit the procedure. This means we will resume the
// command on the next row, but first we need to make sure
// the command did not stop on the last row of the address
// range. So reinitialize iv_canResumeScrub if necessary.

o_rc = didCmdStopOnLastAddr<TYPE_MBA>( iv_chip, MASTER_RANK,
lastAddr, true );
if ( SUCCESS != o_rc )
{
PRDF_ERR( PRDF_FUNC "didCmdStopOnLastAddr(0x%08x) "
"failed", iv_chip->getHuid() );
break;
}
iv_canResumeScrub = !lastAddr;

if ( iv_canResumeScrub )
{
// Indicate that we need to resume the command on the
// next row instead of the next address.
iv_resumeNextRow = true;
}
}
else
{
Expand Down
1 change: 1 addition & 0 deletions src/usr/diag/prdf/plat/mem/prdfMemVcm.H
Original file line number Diff line number Diff line change
Expand Up @@ -329,6 +329,7 @@ class VcmEvent : public TdEntry

const MemMark iv_mark; ///< The chip mark from hardware.
const bool iv_rowRepairEnabled; ///< True if Row Repair is enabled.
bool iv_resumeNextRow = false; ///< True if scrub is resuming on next row.
uint8_t iv_mceCount = 0; ///< MCEs hit count, currently for Row Repair only.
MemAddr iv_rowRepairFailAddr; ///< Address stored to apply Row Repair on.
};
Expand Down
2 changes: 1 addition & 1 deletion src/usr/diag/prdf/plat/mem/prdfMemVcm_ipl.C
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,7 @@ uint32_t VcmEvent<TYPE_MBA>::startCmd()
case TD_PHASE_2:
o_rc = ( iv_canResumeScrub )
? resumeTdSfRead<TYPE_MBA>( iv_chip, MASTER_RANK,
stopCond )
stopCond, iv_resumeNextRow )
: startTdSfRead<TYPE_MBA>( iv_chip, iv_rank, MASTER_RANK,
stopCond );
if ( SUCCESS != o_rc )
Expand Down
3 changes: 2 additions & 1 deletion src/usr/diag/prdf/plat/mem/prdfMemVcm_rt.C
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,8 @@ uint32_t VcmEvent<TYPE_MBA>::startCmd()
{
// Resume the command from the next address to the end of this master
// rank.
o_rc = resumeTdScrub<TYPE_MBA>( iv_chip, MASTER_RANK, stopCond );
o_rc = resumeTdScrub<TYPE_MBA>( iv_chip, MASTER_RANK, stopCond,
iv_resumeNextRow );
if ( SUCCESS != o_rc )
{
PRDF_ERR( PRDF_FUNC "resumeTdScrub(0x%08x) failed",
Expand Down

0 comments on commit 414037d

Please sign in to comment.