diff options
Diffstat (limited to 'src/usr/diag/prdf/plat/prdfPlatServices.C')
-rw-r--r-- | src/usr/diag/prdf/plat/prdfPlatServices.C | 275 |
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 |