diff options
author | Zane Shelley <zshelle@us.ibm.com> | 2016-12-09 16:59:31 -0600 |
---|---|---|
committer | Zane C. Shelley <zshelle@us.ibm.com> | 2016-12-14 17:03:52 -0500 |
commit | 3955c345426f23843108aecb8d240b471cc2e653 (patch) | |
tree | 5d83e0f1bc10f4a5a456d1d5088456463481058b /src/usr/diag/prdf/common/plat/mem/prdfMemMark.C | |
parent | a6ac835e61193f05623a7ae9934407fc784b4b31 (diff) | |
download | talos-hostboot-3955c345426f23843108aecb8d240b471cc2e653.tar.gz talos-hostboot-3955c345426f23843108aecb8d240b471cc2e653.zip |
PRD: Mainline memory MPE analysis
Change-Id: I93e5122cee3eaba7609945e74243fb32b1e9c393
RTC: 165378
Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/33703
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://ralgit01.raleigh.ibm.com/gerrit1/33843
Tested-by: Jenkins OP Build CI <op-jenkins+hostboot@us.ibm.com>
Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com>
Diffstat (limited to 'src/usr/diag/prdf/common/plat/mem/prdfMemMark.C')
-rw-r--r-- | src/usr/diag/prdf/common/plat/mem/prdfMemMark.C | 457 |
1 files changed, 457 insertions, 0 deletions
diff --git a/src/usr/diag/prdf/common/plat/mem/prdfMemMark.C b/src/usr/diag/prdf/common/plat/mem/prdfMemMark.C new file mode 100644 index 000000000..174eca481 --- /dev/null +++ b/src/usr/diag/prdf/common/plat/mem/prdfMemMark.C @@ -0,0 +1,457 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/usr/diag/prdf/common/plat/mem/prdfMemMark.C $ */ +/* */ +/* OpenPOWER HostBoot Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 2016 */ +/* [+] 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 */ + +#include <prdfMemMark.H> + +#include <prdfTrace.H> + +using namespace TARGETING; + +namespace PRDF +{ + +using namespace PlatServices; + +namespace MarkStore +{ + +//############################################################################## +// Utilities to read/write markstore (MCA) +//############################################################################## + +// - We have the ability to set chip marks via the FWMSx registers, but there +// are only eight repairs total that we can use in the FWMSx registers. +// Therefore we will always use the HWMSx registers for the chip marks on +// master ranks and use the FWMSx registers for other repairs. +// - Also, we have the ability in the FWMSx registers to scale the range of +// where the chip/symbol marks are placed (i.e. slave ranks, banks, etc.). +// However, we are still limited to 8 repairs and the complication of +// managing the repairs dynamically to ensure we can place as many repairs as +// possible is more work than what we want to deal with at this time. +// Therefore, we will only use the FWMSx registers to place a single symbol +// mark per master rank. This matches the P8 behavior. This could be improved +// upon later if we have the time, but doubtful. +// - Summary: +// - Chip marks will use HWMS0-7 registers (0x07010AD0-0x07010AD7). +// - Symbol marks will use FWMS0-7 registers (0x07010AD8-0x07010ADF). +// - Each register maps to master ranks 0-7. + +template<> +uint32_t readChipMark<TYPE_MCA>( ExtensibleChip * i_chip, + const MemRank & i_rank, MemMark & o_mark ) +{ + #define PRDF_FUNC "[readChipMark<TYPE_MCA>] " + + uint32_t o_rc = SUCCESS; + o_mark = MemMark(); // ensure invalid + + // get the register name + char msName[64]; + sprintf( msName, "HW_MS%x", i_rank.getMaster() ); + + // get the mark store register + SCAN_COMM_REGISTER_CLASS * hwms = i_chip->getRegister( msName ); + + o_rc = hwms->Read(); + if ( SUCCESS != o_rc ) + { + PRDF_ERR( PRDF_FUNC "Read() failed on %s: i_chip=0x%08x", + msName, i_chip->getHuid() ); + } + else + { + // HWMSx[0:7] contains the Galois field + uint8_t galois = hwms->GetBitFieldJustified(0,8); + + // If the Galois field is zero, do nothing and use the default + // constructor for o_mark + if (0 != galois) + { + // get the target + TargetHandle_t trgt = i_chip->getTrgt(); + + // get the MemMark + o_mark = MemMark(trgt, i_rank, galois); + } + } + + return o_rc; + + #undef PRDF_FUNC +} + +//------------------------------------------------------------------------------ + +template<> +uint32_t writeChipMark<TYPE_MCA>( ExtensibleChip * i_chip, + const MemRank & i_rank, + const MemMark & i_mark ) +{ + #define PRDF_FUNC "[writeChipMark<TYPE_MCA>] " + + PRDF_ASSERT( i_mark.isValid() ); + + uint32_t o_rc = SUCCESS; + + // get the register name + char msName[64]; + sprintf( msName, "HW_MS%x", i_rank.getMaster() ); + + // get the mark store register + SCAN_COMM_REGISTER_CLASS * hwms = i_chip->getRegister( msName ); + + // HWMSx[0:7] set this to the Galois field. + hwms->SetBitFieldJustified( 0, 8, i_mark.getGalois() ); + + // HWMSx[8] confirmed with the hardware team that this will not trigger + // another MPE attention and that they want this set to 1. + hwms->SetBit( 8 ); + + // HWMSx[9] set to 1 to enable exit 1 for markstore reads. This is a + // performance improvement because we know the DRAM is bad. + hwms->SetBit( 9 ); + + o_rc = hwms->Write(); + if ( SUCCESS != o_rc ) + { + PRDF_ERR( PRDF_FUNC "Write() failed on %s: i_chip=0x%08x", + msName, i_chip->getHuid() ); + } + + return o_rc; + + #undef PRDF_FUNC +} + +//------------------------------------------------------------------------------ + +template<> +uint32_t clearChipMark<TYPE_MCA>( ExtensibleChip * i_chip, + const MemRank & i_rank ) +{ + #define PRDF_FUNC "[clearChipMark<TYPE_MCA>] " + + uint32_t o_rc = SUCCESS; + + // get the register name + char msName[64]; + sprintf( msName, "HW_MS%x", i_rank.getMaster() ); + + // get the mark store register + SCAN_COMM_REGISTER_CLASS * hwms = i_chip->getRegister( msName ); + + // Clear the entire HWMSx register. + hwms->clearAllBits(); + + o_rc = hwms->Write(); + if ( SUCCESS != o_rc ) + { + PRDF_ERR( PRDF_FUNC "Write() failed on %s: i_chip=0x%08x", + msName, i_chip->getHuid() ); + } + + return o_rc; + + #undef PRDF_FUNC +} + +//------------------------------------------------------------------------------ + +template<> +uint32_t readSymbolMark<TYPE_MCA>( ExtensibleChip * i_chip, + const MemRank & i_rank, MemMark & o_mark ) +{ + #define PRDF_FUNC "[readSymbolMark<TYPE_MCA>] " + + uint32_t o_rc = SUCCESS; + o_mark = MemMark(); // ensure invalid + + // get the register name + char msName[64]; + sprintf( msName, "FW_MS%x", i_rank.getMaster() ); + + // get the mark store register + SCAN_COMM_REGISTER_CLASS * fwms = i_chip->getRegister( msName ); + + o_rc = fwms->Read(); + if ( SUCCESS != o_rc ) + { + PRDF_ERR( PRDF_FUNC "Read() failed on %s: i_chip=0x%08x", + msName, i_chip->getHuid() ); + } + else + { + // FWMSx[0:7] contains the Galois field + uint8_t galois = fwms->GetBitFieldJustified(0,8); + + // If the Galois field is zero, do nothing and use the default + // constructor for o_mark + if (0 != galois) + { + // check other fields for accuracy - assert on failure + + // FWMSx[8] should be 1 to indicate a symbol mark. + PRDF_ASSERT( fwms->IsBitSet(8) ); + + // FWMSx[9:11] should be 0b101 to indicate master rank. + PRDF_ASSERT( 0x5 == fwms->GetBitFieldJustified(9,3) ); + + // FWMSx[12:14] is the master rank and should match the register + // number. + PRDF_ASSERT( i_rank.getMaster() == + fwms->GetBitFieldJustified(12,3) ); + + // FWMSx[15:22] should be all zeros + PRDF_ASSERT( 0x0 == fwms->GetBitFieldJustified(15,8) ); + + // get the target + TargetHandle_t trgt = i_chip->getTrgt(); + + // get the MemMark + o_mark = MemMark(trgt, i_rank, galois); + } + } + + return o_rc; + + #undef PRDF_FUNC +} + +//------------------------------------------------------------------------------ + +template<> +uint32_t writeSymbolMark<TYPE_MCA>( ExtensibleChip * i_chip, + const MemRank & i_rank, + const MemMark & i_mark ) +{ + #define PRDF_FUNC "[writeSymbolMark<TYPE_MCA>] " + + PRDF_ASSERT( i_mark.isValid() ); + + uint32_t o_rc = SUCCESS; + + // get the register name + char msName[64]; + sprintf( msName, "FW_MS%x", i_rank.getMaster() ); + + // get the mark store register + SCAN_COMM_REGISTER_CLASS * fwms = i_chip->getRegister( msName ); + + // FWMSx[0:7] set this to the Galois field. + fwms->SetBitFieldJustified( 0, 8, i_mark.getGalois() ); + + // FWMSx[8] set to 1 to indicate a symbol mark. + fwms->SetBit( 8 ); + + // FWMSx[9:11] set to 0b101 to indicate master rank. + fwms->SetBitFieldJustified( 9, 3, 0x5 ); + + // FWMSx[12:14] set this to the master rank which should match the + // register number. + fwms->SetBitFieldJustified( 12, 3, i_rank.getMaster() ); + + // FWMSx[15:22] set to all zeros + fwms->SetBitFieldJustified( 15, 8, 0x0 ); + + // FWMSx[23] set to 1 to enable exit 1 for markstore reads. This is a + // performance improvement because we know the symbol is bad. + fwms->SetBit( 23 ); + + o_rc = fwms->Write(); + if ( SUCCESS != o_rc ) + { + PRDF_ERR( PRDF_FUNC "Write() failed on %s: i_chip=0x%08x", + msName, i_chip->getHuid() ); + } + + return o_rc; + + #undef PRDF_FUNC +} + +//------------------------------------------------------------------------------ + +template<> +uint32_t clearSymbolMark<TYPE_MCA>( ExtensibleChip * i_chip, + const MemRank & i_rank ) +{ + #define PRDF_FUNC "[clearSymbolMark<TYPE_MCA>] " + + uint32_t o_rc = SUCCESS; + + // get the register name + char msName[64]; + sprintf( msName, "FW_MS%x", i_rank.getMaster() ); + + // get the mark store register + SCAN_COMM_REGISTER_CLASS * fwms = i_chip->getRegister( msName ); + + // Clear the entire FWMSx register. + fwms->clearAllBits(); + + o_rc = fwms->Write(); + if ( SUCCESS != o_rc ) + { + PRDF_ERR( PRDF_FUNC "Write() failed on %s: i_chip=0x%08x", + msName, i_chip->getHuid() ); + } + + return o_rc; + + #undef PRDF_FUNC +} + +//############################################################################## +// Utilities to read/write markstore (MBA) +//############################################################################## + +template<> +uint32_t readChipMark<TYPE_MBA>( ExtensibleChip * i_chip, + const MemRank & i_rank, MemMark & o_mark ) +{ + #define PRDF_FUNC "[readChipMark<TYPE_MBA>] " + + uint32_t o_rc = SUCCESS; + + o_mark = MemMark(); // ensure invalid + + // TODO: RTC 157888 + + PRDF_ERR( PRDF_FUNC "function not implemented yet" ); + + return o_rc; + + #undef PRDF_FUNC +} + +//------------------------------------------------------------------------------ + +template<> +uint32_t writeChipMark<TYPE_MBA>( ExtensibleChip * i_chip, + const MemRank & i_rank, + const MemMark & i_mark ) +{ + #define PRDF_FUNC "[writeChipMark<TYPE_MBA>] " + + PRDF_ASSERT( i_mark.isValid() ); + + uint32_t o_rc = SUCCESS; + + // TODO: RTC 157888 + + PRDF_ERR( PRDF_FUNC "function not implemented yet" ); + + return o_rc; + + #undef PRDF_FUNC +} + +//------------------------------------------------------------------------------ + +template<> +uint32_t clearChipMark<TYPE_MBA>( ExtensibleChip * i_chip, + const MemRank & i_rank ) +{ + #define PRDF_FUNC "[clearChipMark<TYPE_MBA>] " + + uint32_t o_rc = SUCCESS; + + // TODO: RTC 157888 + + PRDF_ERR( PRDF_FUNC "function not implemented yet" ); + + return o_rc; + + #undef PRDF_FUNC +} + +//------------------------------------------------------------------------------ + +template<> +uint32_t readSymbolMark<TYPE_MBA>( ExtensibleChip * i_chip, + const MemRank & i_rank, MemMark & o_mark ) +{ + #define PRDF_FUNC "[readSymbolMark<TYPE_MBA>] " + + uint32_t o_rc = SUCCESS; + + o_mark = MemMark(); // ensure invalid + + // TODO: RTC 157888 + + PRDF_ERR( PRDF_FUNC "function not implemented yet" ); + + return o_rc; + + #undef PRDF_FUNC +} + +//------------------------------------------------------------------------------ + +template<> +uint32_t writeSymbolMark<TYPE_MBA>( ExtensibleChip * i_chip, + const MemRank & i_rank, + const MemMark & i_mark ) +{ + #define PRDF_FUNC "[writeSymbolMark<TYPE_MBA>] " + + PRDF_ASSERT( i_mark.isValid() ); + + uint32_t o_rc = SUCCESS; + + // TODO: RTC 157888 + + PRDF_ERR( PRDF_FUNC "function not implemented yet" ); + + return o_rc; + + #undef PRDF_FUNC +} + +//------------------------------------------------------------------------------ + +template<> +uint32_t clearSymbolMark<TYPE_MBA>( ExtensibleChip * i_chip, + const MemRank & i_rank ) +{ + #define PRDF_FUNC "[clearSymbolMark<TYPE_MBA>] " + + uint32_t o_rc = SUCCESS; + + // TODO: RTC 157888 + + PRDF_ERR( PRDF_FUNC "function not implemented yet" ); + + return o_rc; + + #undef PRDF_FUNC +} + +//------------------------------------------------------------------------------ + +} // end namespace MarkStore + +} // end namespace PRDF + |