summaryrefslogtreecommitdiffstats
path: root/src/usr/diag/prdf/plat/prdfPlatServices.C
diff options
context:
space:
mode:
Diffstat (limited to 'src/usr/diag/prdf/plat/prdfPlatServices.C')
-rw-r--r--src/usr/diag/prdf/plat/prdfPlatServices.C275
1 files changed, 190 insertions, 85 deletions
diff --git a/src/usr/diag/prdf/plat/prdfPlatServices.C b/src/usr/diag/prdf/plat/prdfPlatServices.C
index 8c17c2fd9..0ad247134 100644
--- a/src/usr/diag/prdf/plat/prdfPlatServices.C
+++ b/src/usr/diag/prdf/plat/prdfPlatServices.C
@@ -40,6 +40,8 @@
#include <prdfRegisterCache.H>
#include <prdfCenMbaDataBundle.H>
+#include <prdfP9McbistDataBundle.H>
+#include <prdfOcmbDataBundle.H>
#include <prdfMemScrubUtils.H>
#include <iipServiceDataCollector.h>
@@ -50,7 +52,7 @@
#include <time.h>
#include <initservice/initserviceif.H>
#include <devicefw/userif.H>
-#include <iipMopRegisterAccess.h>
+#include <prdfHomRegisterAccess.H>
#include <ibscomreasoncodes.H>
#include <scom/scomreasoncodes.H>
#include <p9_proc_gettracearray.H>
@@ -58,6 +60,13 @@
#include <p9c_mss_maint_cmds.H>
#include <prdfParserUtils.H>
#include <p9c_mss_rowRepairFuncs.H>
+#include <errl/errludlogregister.H>
+
+#include <hwp_wrappers.H>
+
+#ifdef CONFIG_NVDIMM
+#include <nvdimm.H>
+#endif
using namespace TARGETING;
@@ -387,31 +396,31 @@ uint32_t getMemAddrRange<TYPE_MCA>( ExtensibleChip * i_chip,
//------------------------------------------------------------------------------
template<>
-uint32_t getMemAddrRange<TYPE_MEM_PORT>( ExtensibleChip * i_chip,
- const MemRank & i_rank,
- mss::mcbist::address & o_startAddr,
- mss::mcbist::address & o_endAddr,
- AddrRangeType i_rangeType )
+uint32_t getMemAddrRange<TYPE_OCMB_CHIP>( ExtensibleChip * i_chip,
+ const MemRank & i_rank,
+ mss::mcbist::address & o_startAddr,
+ mss::mcbist::address & o_endAddr,
+ AddrRangeType i_rangeType )
{
- #define PRDF_FUNC "[PlatServices::getMemAddrRange<TYPE_MEM_PORT>] "
+ #define PRDF_FUNC "[PlatServices::getMemAddrRange<TYPE_OCMB_CHIP>] "
- PRDF_ASSERT( nullptr != i_chip );
- PRDF_ASSERT( TYPE_MEM_PORT == i_chip->getType() );
+ #ifdef CONFIG_AXONE
- /* TODO RTC 207273 - no HWP support yet
- uint32_t port = i_chip->getPos() % MAX_PORT_PER_OCMB;
+ PRDF_ASSERT( nullptr != i_chip );
+ PRDF_ASSERT( TYPE_OCMB_CHIP == i_chip->getType() );
+ // TODO RTC 210072 - support for multiple ports
if ( SLAVE_RANK == i_rangeType )
{
FAPI_CALL_HWP_NORETURN( mss::mcbist::address::get_srank_range,
- port, i_rank.getDimmSlct(),
+ 0, i_rank.getDimmSlct(),
i_rank.getRankSlct(), i_rank.getSlave(),
o_startAddr, o_endAddr );
}
else if ( MASTER_RANK == i_rangeType )
{
FAPI_CALL_HWP_NORETURN( mss::mcbist::address::get_mrank_range,
- port, i_rank.getDimmSlct(),
+ 0, i_rank.getDimmSlct(),
i_rank.getRankSlct(), o_startAddr, o_endAddr );
}
else
@@ -419,7 +428,8 @@ uint32_t getMemAddrRange<TYPE_MEM_PORT>( ExtensibleChip * i_chip,
PRDF_ERR( PRDF_FUNC "unsupported range type %d", i_rangeType );
PRDF_ASSERT(false);
}
- */
+
+ #endif
return SUCCESS;
@@ -520,15 +530,15 @@ uint32_t getMemAddrRange<TYPE_MCA>( ExtensibleChip * i_chip,
//------------------------------------------------------------------------------
template<>
-uint32_t getMemAddrRange<TYPE_MEM_PORT>( ExtensibleChip * i_chip,
- const MemRank & i_rank,
- MemAddr & o_startAddr,
- MemAddr & o_endAddr,
- AddrRangeType i_rangeType )
+uint32_t getMemAddrRange<TYPE_OCMB_CHIP>( ExtensibleChip * i_chip,
+ const MemRank & i_rank,
+ MemAddr & o_startAddr,
+ MemAddr & o_endAddr,
+ AddrRangeType i_rangeType )
{
mss::mcbist::address saddr, eaddr;
- uint32_t o_rc = getMemAddrRange<TYPE_MEM_PORT>( i_chip, i_rank, saddr,
- eaddr, i_rangeType );
+ uint32_t o_rc = getMemAddrRange<TYPE_OCMB_CHIP>( i_chip, i_rank, saddr,
+ eaddr, i_rangeType );
if ( SUCCESS == o_rc )
{
o_startAddr = __convertMssMcbistAddr( saddr );
@@ -630,16 +640,16 @@ uint32_t getMemAddrRange<TYPE_MCA>( ExtensibleChip * i_chip,
uint8_t i_dimmSlct );
template
-uint32_t getMemAddrRange<TYPE_MEM_PORT>( ExtensibleChip * i_chip,
- mss::mcbist::address & o_startAddr,
- mss::mcbist::address & o_endAddr,
- uint8_t i_dimmSlct );
+uint32_t getMemAddrRange<TYPE_OCMB_CHIP>( ExtensibleChip * i_chip,
+ mss::mcbist::address & o_startAddr,
+ mss::mcbist::address & o_endAddr,
+ uint8_t i_dimmSlct );
template
-uint32_t getMemAddrRange<TYPE_MEM_PORT>( ExtensibleChip * i_chip,
- MemAddr & o_startAddr,
- MemAddr & o_endAddr,
- uint8_t i_dimmSlct );
+uint32_t getMemAddrRange<TYPE_OCMB_CHIP>( ExtensibleChip * i_chip,
+ MemAddr & o_startAddr,
+ MemAddr & o_endAddr,
+ uint8_t i_dimmSlct );
//------------------------------------------------------------------------------
@@ -696,17 +706,16 @@ bool isRowRepairEnabled<TYPE_MCA>( ExtensibleChip * i_chip,
}
template<>
-bool isRowRepairEnabled<TYPE_MEM_PORT>( ExtensibleChip * i_chip,
- const MemRank & i_rank )
+bool isRowRepairEnabled<TYPE_OCMB_CHIP>( ExtensibleChip * i_chip,
+ const MemRank & i_rank )
{
- #define PRDF_FUNC "[PlatServices::isRowRepairEnabled<TYPE_MEM_PORT>] "
+ #define PRDF_FUNC "[PlatServices::isRowRepairEnabled<TYPE_OCMB_CHIP>] "
PRDF_ASSERT( nullptr != i_chip );
- PRDF_ASSERT( TYPE_MEM_PORT == i_chip->getType() );
+ PRDF_ASSERT( TYPE_OCMB_CHIP == i_chip->getType() );
bool o_isEnabled = false;
- /* TODO RTC 207273 - no HWP support yet
do
{
// Don't do row repair if DRAM repairs is disabled.
@@ -732,13 +741,110 @@ bool isRowRepairEnabled<TYPE_MEM_PORT>( ExtensibleChip * i_chip,
}
}while(0);
- */
return o_isEnabled;
#undef PRDF_FUNC
}
+//------------------------------------------------------------------------------
+
+#ifdef CONFIG_NVDIMM
+uint32_t nvdimmNotifyProtChange( TARGETING::TargetHandle_t i_target,
+ const NVDIMM::nvdimm_protection_t i_state )
+{
+ #define PRDF_FUNC "[PlatServices::nvdimmNotifyProtChange] "
+
+ uint32_t o_rc = SUCCESS;
+
+ errlHndl_t errl = NVDIMM::notifyNvdimmProtectionChange( i_target, i_state );
+ if ( nullptr != errl )
+ {
+ PRDF_ERR( PRDF_FUNC "NVDIMM::notifyNvdimmProtectionChange(0x%08x) "
+ "failed.", getHuid(i_target) );
+ PRDF_COMMIT_ERRL( errl, ERRL_ACTION_REPORT );
+ o_rc = FAIL;
+ }
+
+ return o_rc;
+
+ #undef PRDF_FUNC
+
+}
+
+void nvdimmAddFfdc( TARGETING::TargetHandle_t i_nvdimm, errlHndl_t & io_errl )
+{
+ #define PRDF_FUNC "[PlatServices::nvdimmAddFfdc] "
+ // Add Page 4 Regs and Vendor Log using external Hostboot interfaces.
+ NVDIMM::nvdimmAddPage4Regs( i_nvdimm, io_errl );
+ NVDIMM::nvdimmAddVendorLog( i_nvdimm, io_errl );
+
+ // Add PRD specific registers relevant to runtime NVDIMM analysis.
+ const uint16_t regList[] =
+ {
+ // Module health registers
+ NVDIMM::i2cReg::MODULE_HEALTH,
+ NVDIMM::i2cReg::MODULE_HEALTH_STATUS0,
+ NVDIMM::i2cReg::MODULE_HEALTH_STATUS1,
+
+ // Threshold status registers
+ NVDIMM::i2cReg::ERROR_THRESHOLD_STATUS,
+ NVDIMM::i2cReg::WARNING_THRESHOLD_STATUS,
+
+ // ES_TEMP registers
+ NVDIMM::i2cReg::ES_TEMP0,
+ NVDIMM::i2cReg::ES_TEMP1,
+ NVDIMM::i2cReg::ES_TEMP_WARNING_HIGH_THRESHOLD0,
+ NVDIMM::i2cReg::ES_TEMP_WARNING_HIGH_THRESHOLD1,
+ NVDIMM::i2cReg::ES_TEMP_WARNING_LOW_THRESHOLD0,
+ NVDIMM::i2cReg::ES_TEMP_WARNING_LOW_THRESHOLD1,
+
+ // NVM Lifetime registers
+ NVDIMM::i2cReg::NVM_LIFETIME,
+ NVDIMM::i2cReg::NVM_LIFETIME_ERROR_THRESHOLD,
+ NVDIMM::i2cReg::NVM_LIFETIME_WARNING_THRESHOLD,
+
+ // ES Lifetime registers
+ NVDIMM::i2cReg::ES_LIFETIME,
+ NVDIMM::i2cReg::ES_LIFETIME_ERROR_THRESHOLD,
+ NVDIMM::i2cReg::ES_LIFETIME_WARNING_THRESHOLD,
+
+ // Status registers
+ NVDIMM::i2cReg::ERASE_STATUS,
+ NVDIMM::i2cReg::ARM_STATUS,
+ NVDIMM::i2cReg::SET_EVENT_NOTIFICATION_STATUS,
+ };
+
+ ERRORLOG::ErrlUserDetailsLogRegister regUd( i_nvdimm );
+ for ( auto const & reg : regList )
+ {
+ // NVDIMM register size = 1 byte
+ size_t NVDIMM_SIZE = 1;
+
+ uint8_t data = 0;
+ errlHndl_t errl = deviceRead( i_nvdimm, &data, NVDIMM_SIZE,
+ DEVICE_NVDIMM_ADDRESS(reg) );
+ if ( errl )
+ {
+ PRDF_ERR( PRDF_FUNC "Failed to read register 0x%X on "
+ "NVDIMM HUID: 0x%08x", reg, getHuid(i_nvdimm) );
+ // Don't commit, just delete the error and continue
+ delete errl; errl = nullptr;
+ continue;
+ }
+ // Only add registers that have non-zero data.
+ if ( 0 == data ) continue;
+
+ regUd.addDataBuffer( &data, sizeof(data), DEVICE_NVDIMM_ADDRESS(reg) );
+ }
+
+ regUd.addToLog( io_errl );
+
+ #undef PRDF_FUNC
+}
+
+#endif
+
//##############################################################################
//## Nimbus Maintenance Command wrappers
//##############################################################################
@@ -758,10 +864,16 @@ uint32_t startBgScrub<TYPE_MCA>( ExtensibleChip * i_mcaChip,
ExtensibleChip * mcbChip = getConnectedParent( i_mcaChip, TYPE_MCBIST );
fapi2::Target<fapi2::TARGET_TYPE_MCBIST> fapiTrgt ( mcbChip->getTrgt() );
+ #ifdef __HOSTBOOT_RUNTIME
+ // Starting a new command. Clear the UE and CE scrub stop counters
+ getMcbistDataBundle( mcbChip )->iv_ueStopCounter.reset();
+ getMcbistDataBundle( mcbChip )->iv_ceStopCounter.reset();
+ #endif
+
// Get the stop conditions.
// NOTE: If HBRT_PRD is not configured, we want to use the defaults so that
// background scrubbing never stops.
- mss::mcbist::stop_conditions stopCond;
+ mss::mcbist::stop_conditions<> stopCond;
// AUEs are checkstop attentions. Unfortunately, MCBIST commands do not stop
// when the system checkstops. Therefore, we must set the stop condition for
@@ -851,11 +963,11 @@ uint32_t startBgScrub<TYPE_MCBIST>( ExtensibleChip * i_mcaChip,
//------------------------------------------------------------------------------
+#ifndef CONFIG_AXONE
template<>
uint32_t startTdScrub<TYPE_MCA>( ExtensibleChip * i_chip,
- const MemRank & i_rank,
- AddrRangeType i_rangeType,
- mss::mcbist::stop_conditions i_stopCond )
+ const MemRank & i_rank, AddrRangeType i_rangeType,
+ mss::mcbist::stop_conditions<mss::mc_type::NIMBUS> i_stopCond )
{
#define PRDF_FUNC "[PlatServices::startTdScrub<TYPE_MCA>] "
@@ -912,6 +1024,7 @@ uint32_t startTdScrub<TYPE_MCA>( ExtensibleChip * i_chip,
#undef PRDF_FUNC
}
+#endif
//##############################################################################
//## Centaur Maintenance Command wrappers
@@ -1316,25 +1429,31 @@ uint32_t incMaintAddr<TYPE_MBA>( ExtensibleChip * i_chip,
//##############################################################################
template<>
-uint32_t startBgScrub<TYPE_MEM_PORT>( ExtensibleChip * i_memPort,
- const MemRank & i_rank )
+uint32_t startBgScrub<TYPE_OCMB_CHIP>( ExtensibleChip * i_ocmb,
+ const MemRank & i_rank )
{
- #define PRDF_FUNC "[PlatServices::startBgScrub<TYPE_MEM_PORT>] "
+ #define PRDF_FUNC "[PlatServices::startBgScrub<TYPE_OCMB_CHIP>] "
- PRDF_ASSERT( nullptr != i_memPort );
- PRDF_ASSERT( TYPE_MEM_PORT == i_memPort->getType() );
+ PRDF_ASSERT( nullptr != i_ocmb );
+ PRDF_ASSERT( TYPE_OCMB_CHIP == i_ocmb->getType() );
uint32_t o_rc = SUCCESS;
- /* TODO RTC 207273 - no HWP support yet
+ #ifdef CONFIG_AXONE
+
// Get the OCMB fapi target
- ExtensibleChip * ocmbChip = getConnectedParent( i_memPort, TYPE_OCMB_CHIP );
- fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP> fapiTrgt (ocmbChip->getTrgt());
+ fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP> fapiTrgt (i_ocmb->getTrgt());
+
+ #ifdef __HOSTBOOT_RUNTIME
+ // Starting a new command. Clear the UE and CE scrub stop counters
+ getOcmbDataBundle( i_ocmb )->iv_ueStopCounter.reset();
+ getOcmbDataBundle( i_ocmb )->iv_ceStopCounter.reset();
+ #endif
// Get the stop conditions.
// NOTE: If HBRT_PRD is not configured, we want to use the defaults so that
// background scrubbing never stops.
- mss::mcbist::stop_conditions stopCond;
+ mss::mcbist::stop_conditions<mss::mc_type::EXPLORER> stopCond;
// AUEs are checkstop attentions. Unfortunately, MCBIST commands do not stop
// when the system checkstops. Therefore, we must set the stop condition for
@@ -1373,40 +1492,40 @@ uint32_t startBgScrub<TYPE_MEM_PORT>( ExtensibleChip * i_memPort,
{
// Get the first address of the given rank.
mss::mcbist::address saddr, eaddr;
- o_rc = getMemAddrRange<TYPE_MEM_PORT>( i_memPort, i_rank, saddr, eaddr,
- SLAVE_RANK );
+ o_rc = getMemAddrRange<TYPE_OCMB_CHIP>( i_ocmb, i_rank, saddr, eaddr,
+ SLAVE_RANK );
if ( SUCCESS != o_rc )
{
PRDF_ERR( PRDF_FUNC "getMemAddrRange(0x%08x,0x%2x) failed",
- i_memPort->getHuid(), i_rank.getKey() );
+ i_ocmb->getHuid(), i_rank.getKey() );
break;
}
// Clear all of the counters and maintenance ECC attentions.
- o_rc = prepareNextCmd<TYPE_OCMB_CHIP>( ocmbChip );
+ o_rc = prepareNextCmd<TYPE_OCMB_CHIP>( i_ocmb );
if ( SUCCESS != o_rc )
{
PRDF_ERR( PRDF_FUNC "prepareNextCmd(0x%08x) failed",
- ocmbChip->getHuid() );
+ i_ocmb->getHuid() );
break;
}
// Start the background scrub command.
errlHndl_t errl = nullptr;
- FAPI_INVOKE_HWP( errl, mss::memdiags::background_scrub, fapiTrgt,
+ FAPI_INVOKE_HWP( errl, exp_background_scrub, fapiTrgt,
stopCond, scrubSpeed, saddr );
if ( nullptr != errl )
{
- PRDF_ERR( PRDF_FUNC "mss::memdiags::background_scrub(0x%08x,%d) "
- "failed", ocmbChip->getHuid(), i_rank.getMaster() );
+ PRDF_ERR( PRDF_FUNC "exp_background_scrub(0x%08x,%d) "
+ "failed", i_ocmb->getHuid(), i_rank.getMaster() );
PRDF_COMMIT_ERRL( errl, ERRL_ACTION_REPORT );
o_rc = FAIL; break;
}
} while (0);
+ #endif
- */
return o_rc;
#undef PRDF_FUNC
@@ -1414,31 +1533,19 @@ uint32_t startBgScrub<TYPE_MEM_PORT>( ExtensibleChip * i_memPort,
//------------------------------------------------------------------------------
-// This specialization only exists to avoid a lot of extra code in some classes.
-// The input chip must still be a MEM_PORT.
-template<>
-uint32_t startBgScrub<TYPE_OCMB_CHIP>( ExtensibleChip * i_memPort,
- const MemRank & i_rank )
-{
- return startBgScrub<TYPE_MEM_PORT>( i_memPort, i_rank );
-}
-
-//------------------------------------------------------------------------------
-
+#ifdef CONFIG_AXONE
template<>
-uint32_t startTdScrub<TYPE_MEM_PORT>( ExtensibleChip * i_chip,
- const MemRank & i_rank,
- AddrRangeType i_rangeType,
- mss::mcbist::stop_conditions i_stopCond )
+uint32_t startTdScrub<TYPE_OCMB_CHIP>(ExtensibleChip * i_chip,
+ const MemRank & i_rank, AddrRangeType i_rangeType,
+ mss::mcbist::stop_conditions<mss::mc_type::EXPLORER> i_stopCond)
{
- #define PRDF_FUNC "[PlatServices::startTdScrub<TYPE_MEM_PORT>] "
+ #define PRDF_FUNC "[PlatServices::startTdScrub<TYPE_OCMB_CHIP>] "
PRDF_ASSERT( nullptr != i_chip );
- PRDF_ASSERT( TYPE_MEM_PORT == i_chip->getType() );
+ PRDF_ASSERT( TYPE_OCMB_CHIP == i_chip->getType() );
uint32_t o_rc = SUCCESS;
- /* TODO RTC 207273 - no HWP support yet
// Set stop-on-AUE for all target scrubs. See explanation in startBgScrub()
// for the reasons why.
i_stopCond.set_pause_on_aue(mss::ON);
@@ -1447,8 +1554,8 @@ uint32_t startTdScrub<TYPE_MEM_PORT>( ExtensibleChip * i_chip,
{
// Get the address range of the given rank.
mss::mcbist::address saddr, eaddr;
- o_rc = getMemAddrRange<TYPE_MEM_PORT>( i_chip, i_rank, saddr, eaddr,
- i_rangeType );
+ o_rc = getMemAddrRange<TYPE_OCMB_CHIP>( i_chip, i_rank, saddr, eaddr,
+ i_rangeType );
if ( SUCCESS != o_rc )
{
PRDF_ERR( PRDF_FUNC "getMemAddrRange(0x%08x,0x%2x) failed",
@@ -1457,12 +1564,10 @@ uint32_t startTdScrub<TYPE_MEM_PORT>( ExtensibleChip * i_chip,
}
// Get the OCMB_CHIP fapi target.
- ExtensibleChip * ocmbChip = getConnectedParent(i_chip, TYPE_OCMB_CHIP);
- fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>
- fapiTrgt(ocmbChip->getTrgt());
+ fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP> fapiTrgt(i_chip->getTrgt());
// Clear all of the counters and maintenance ECC attentions.
- o_rc = prepareNextCmd<TYPE_OCMB_CHIP>( ocmbChip );
+ o_rc = prepareNextCmd<TYPE_OCMB_CHIP>( i_chip );
if ( SUCCESS != o_rc )
{
PRDF_ERR( PRDF_FUNC "prepareNextCmd(0x%08x) failed",
@@ -1472,23 +1577,23 @@ uint32_t startTdScrub<TYPE_MEM_PORT>( ExtensibleChip * i_chip,
// Start targeted scrub command.
errlHndl_t errl = nullptr;
- FAPI_INVOKE_HWP( errl, mss::memdiags::targeted_scrub, fapiTrgt,
+ FAPI_INVOKE_HWP( errl, exp_targeted_scrub, fapiTrgt,
i_stopCond, saddr, eaddr, mss::mcbist::NONE );
if ( nullptr != errl )
{
- PRDF_ERR( PRDF_FUNC "mss::memdiags::targeted_scrub(0x%08x,0x%02x) "
- "failed", ocmbChip->getHuid(), i_rank.getKey() );
+ PRDF_ERR( PRDF_FUNC "exp_targeted_scrub(0x%08x,0x%02x) "
+ "failed", i_chip->getHuid(), i_rank.getKey() );
PRDF_COMMIT_ERRL( errl, ERRL_ACTION_REPORT );
o_rc = FAIL; break;
}
} while (0);
- */
return o_rc;
#undef PRDF_FUNC
}
+#endif
//##############################################################################
//## Core/cache trace array functions
OpenPOWER on IntegriCloud