Skip to content

Commit

Permalink
PRD: resume command support in VcmEvent for Row Repair
Browse files Browse the repository at this point in the history
Change-Id: I2d1faf7303b6c334b4107891994b8b89c53ade36
RTC: 196073
Reviewed-on: http://rchgit01.rchland.ibm.com/gerrit1/64144
Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com>
Reviewed-by: Caleb N. Palmer <cnpalmer@us.ibm.com>
Reviewed-by: Brian J. Stegmiller <bjs@us.ibm.com>
Reviewed-by: Zane C. Shelley <zshelle@us.ibm.com>
Reviewed-on: http://rchgit01.rchland.ibm.com/gerrit1/64557
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
zane131 committed Aug 16, 2018
1 parent 4f0f9f1 commit 396c1d3
Show file tree
Hide file tree
Showing 6 changed files with 226 additions and 162 deletions.
2 changes: 0 additions & 2 deletions src/usr/diag/prdf/plat/mem/prdfMemTdQueue.H
Original file line number Diff line number Diff line change
Expand Up @@ -150,11 +150,9 @@ class TdEntry
// used for displaying FFDC in the TD controller.
const MemRank iv_rank; ///< The rank in which this event occurred.

#ifdef __HOSTBOOT_RUNTIME
/** True if the current TD command can be resumed, false otherwise. Resume
* only supported for MBA at this time. */
bool iv_canResumeScrub = false;
#endif
};

//------------------------------------------------------------------------------
Expand Down
191 changes: 191 additions & 0 deletions src/usr/diag/prdf/plat/mem/prdfMemVcm.C
Original file line number Diff line number Diff line change
@@ -0,0 +1,191 @@
/* IBM_PROLOG_BEGIN_TAG */
/* This is an automatically generated prolog. */
/* */
/* $Source: src/usr/diag/prdf/plat/mem/prdfMemVcm.C $ */
/* */
/* OpenPOWER HostBoot Project */
/* */
/* Contributors Listed Below - COPYRIGHT 2018 */
/* [+] International Business Machines Corp. */
/* */
/* */
/* Licensed under the Apache License, Version 2.0 (the "License"); */
/* you may not use this file except in compliance with the License. */
/* You may obtain a copy of the License at */
/* */
/* http://www.apache.org/licenses/LICENSE-2.0 */
/* */
/* Unless required by applicable law or agreed to in writing, software */
/* distributed under the License is distributed on an "AS IS" BASIS, */
/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
/* implied. See the License for the specific language governing */
/* permissions and limitations under the License. */
/* */
/* IBM_PROLOG_END_TAG */

/** @file prdfMemVcm.C */

#include <prdfMemVcm.H>

// Platform includes
#include <prdfCenMbaExtraSig.H>

using namespace TARGETING;

namespace PRDF
{

using namespace PlatServices;

//##############################################################################
//
// Specializations for MCA
//
//##############################################################################

template<>
uint32_t VcmEvent<TYPE_MCA>::handlePhaseComplete( const uint32_t & i_eccAttns,
STEP_CODE_DATA_STRUCT & io_sc,
bool & o_done )
{
#define PRDF_FUNC "[VcmEvent<TYPE_MCA>::handlePhaseComplete] "

uint32_t o_rc = SUCCESS;

do
{
if ( TD_PHASE_2 == iv_phase )
{
// Determine if the chip mark has been verified.
o_rc = (i_eccAttns & MAINT_MCE) ? verified(io_sc)
: falseAlarm(io_sc);
if ( SUCCESS != o_rc )
{
PRDF_ERR( PRDF_FUNC "verified()/falseAlarm() failed" );
break;
}

o_done = true; // Procedure is complete.
}

} while (0);

return o_rc;

#undef PRDF_FUNC
}

//##############################################################################
//
// Specializations for MBA
//
//##############################################################################

template<>
uint32_t VcmEvent<TYPE_MBA>::startNextPhase( STEP_CODE_DATA_STRUCT & io_sc )
{
uint32_t signature = 0;

if ( iv_canResumeScrub )
{
signature = PRDFSIG_VcmResume;

PRDF_TRAC( "[VcmEvent] Resuming VCM Phase %d: 0x%08x,0x%02x",
iv_phase, iv_chip->getHuid(), getKey() );
}
else
{
switch ( iv_phase )
{
case TD_PHASE_0:
iv_phase = TD_PHASE_1;
signature = PRDFSIG_StartVcmPhase1;
break;

case TD_PHASE_1:
iv_phase = TD_PHASE_2;
signature = PRDFSIG_StartVcmPhase2;
break;

default: PRDF_ASSERT( false ); // invalid phase
}

PRDF_TRAC( "[VcmEvent] Starting VCM Phase %d: 0x%08x,0x%02x",
iv_phase, iv_chip->getHuid(), getKey() );
}

io_sc.service_data->AddSignatureList( iv_chip->getTrgt(), signature );

return startCmd();
}

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

template<>
uint32_t VcmEvent<TYPE_MBA>::handlePhaseComplete( const uint32_t & i_eccAttns,
STEP_CODE_DATA_STRUCT & io_sc,
bool & o_done )
{
#define PRDF_FUNC "[VcmEvent<TYPE_MBA>::handlePhaseComplete] "

uint32_t o_rc = SUCCESS;

do
{
// Determine if the command stopped on the last address.
bool lastAddr = false;
o_rc = didCmdStopOnLastAddr<TYPE_MBA>( iv_chip, MASTER_RANK, lastAddr );
if ( SUCCESS != o_rc )
{
PRDF_ERR( PRDF_FUNC "didCmdStopOnLastAddr(0x%08x) failed",
iv_chip->getHuid() );
break;
}

// It is important to initialize iv_canResumeScrub here, so that we will
// know to resume the current phase in startNextPhase() instead of
// starting phase.
iv_canResumeScrub = !lastAddr;

if ( TD_PHASE_2 == iv_phase )
{
if ( i_eccAttns & MAINT_MCE )
{
// The chip mark has been verified.
o_rc = verified( io_sc );
if ( SUCCESS != o_rc )
{
PRDF_ERR( PRDF_FUNC "verified() failed on 0x%08x",
iv_chip->getHuid() );
break;
}

o_done = true; // Procedure is complete.
}
else if ( !iv_canResumeScrub )
{
// The chip mark is not verified and the command has reached the
// end of the rank. So this is a false alarm.
o_rc = falseAlarm( io_sc );
if ( SUCCESS != o_rc )
{
PRDF_ERR( PRDF_FUNC "falseAlarm() failed on 0x%08x",
iv_chip->getHuid() );
break;
}

o_done = true; // Procedure is complete.
}
}

} while (0);

return o_rc;

#undef PRDF_FUNC
}

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

} // end namespace PRDF

32 changes: 20 additions & 12 deletions src/usr/diag/prdf/plat/mem/prdfMemVcm.H
Original file line number Diff line number Diff line change
Expand Up @@ -192,19 +192,13 @@ class VcmEvent : public TdEntry

if ( o_done ) break; // abort the procedure.

if ( TD_PHASE_2 == iv_phase )
// Complete the phase.
o_rc = handlePhaseComplete( eccAttns, io_sc, o_done );
if ( SUCCESS != o_rc )
{
// Determine if the chip mark has been verified.
o_rc = (eccAttns & MAINT_MCE) ? verified(io_sc)
: falseAlarm(io_sc);
if ( SUCCESS != o_rc )
{
PRDF_ERR( PRDF_FUNC "verified()/falseAlarm() failed" );
break;
}

// Procedure is complete.
o_done = true;
PRDF_ERR( PRDF_FUNC "checkEcc() failed on 0x%08x",
iv_chip->getHuid() );
break;
}

} while (0);
Expand Down Expand Up @@ -234,6 +228,20 @@ class VcmEvent : public TdEntry
uint32_t checkEcc( const uint32_t & i_eccAttns,
STEP_CODE_DATA_STRUCT & io_sc, bool & o_done );

/**
* @brief Does appropriate actions at the end of a phase if it was not
* aborted due to an error. Note that the actions will differ per
* target type, runtime/IPL, or if there is an MCE on phase 2.
* @param i_eccAttns Mask of all currently active maintenance attentions.
* See enum MaintEccAttns for values.
* @param io_sc The step code data struct.
* @param o_done True if the procedure is complete or has aborted.
* @return Non-SUCCESS if an internal function fails, SUCCESS otherwise.
*/
uint32_t handlePhaseComplete( const uint32_t & i_eccAttns,
STEP_CODE_DATA_STRUCT & io_sc,
bool & o_done );

/**
* @brief The chip mark is verified. Do additional processing such as
* updating the VPD and initiating DRAM sparing, if supported.
Expand Down
24 changes: 14 additions & 10 deletions src/usr/diag/prdf/plat/mem/prdfMemVcm_ipl.C
Original file line number Diff line number Diff line change
Expand Up @@ -202,24 +202,28 @@ uint32_t VcmEvent<TYPE_MBA>::startCmd()
switch ( iv_phase )
{
case TD_PHASE_1:
// Start the steer cleanup procedure on this master rank.
o_rc = startTdSteerCleanup<TYPE_MBA>( iv_chip, iv_rank, MASTER_RANK,
stopCond );
o_rc = ( iv_canResumeScrub )
? resumeTdSteerCleanup<TYPE_MBA>( iv_chip, MASTER_RANK,
stopCond )
: startTdSteerCleanup<TYPE_MBA>( iv_chip, iv_rank,
MASTER_RANK, stopCond );
if ( SUCCESS != o_rc )
{
PRDF_ERR( PRDF_FUNC "startTdSteerCleanup(0x%08x,0x%2x) failed",
iv_chip->getHuid(), getKey() );
PRDF_ERR( PRDF_FUNC "steer cleanup command failed on 0x%08x",
iv_chip->getHuid() );
}
break;

case TD_PHASE_2:
// Start the superfast read procedure on this master rank.
o_rc = startTdSfRead<TYPE_MBA>( iv_chip, iv_rank, MASTER_RANK,
stopCond );
o_rc = ( iv_canResumeScrub )
? resumeTdSfRead<TYPE_MBA>( iv_chip, MASTER_RANK,
stopCond )
: startTdSfRead<TYPE_MBA>( iv_chip, iv_rank, MASTER_RANK,
stopCond );
if ( SUCCESS != o_rc )
{
PRDF_ERR( PRDF_FUNC "startTdSfRead(0x%08x,0x%2x) failed",
iv_chip->getHuid(), getKey() );
PRDF_ERR( PRDF_FUNC "sf read command failed on 0x%08x",
iv_chip->getHuid() );
}
break;

Expand Down

0 comments on commit 396c1d3

Please sign in to comment.