diff options
author | Brian Silver <bsilver@us.ibm.com> | 2016-01-22 06:22:02 -0600 |
---|---|---|
committer | Daniel M. Crowell <dcrowell@us.ibm.com> | 2016-04-01 21:22:34 -0400 |
commit | 54fa8bf62ae4e8ccdac831b792cd2e8951bf32b3 (patch) | |
tree | cf98d9f666780ebf0ff3794c3d069be952ac020b /src | |
parent | 552bf3a724e5e4358c8bc340f08ffdc8e8625082 (diff) | |
download | blackbird-hostboot-54fa8bf62ae4e8ccdac831b792cd2e8951bf32b3.tar.gz blackbird-hostboot-54fa8bf62ae4e8ccdac831b792cd2e8951bf32b3.zip |
Change polling to include probes, add granular training controls
Change-Id: Ic08df810970b2448e67f9aab5b7f934cb518f2bc
Original-Change-Id: I0c8c44e4f9627f96f8f66195ff71bb0b6113ce47
Reviewed-on: http://gfw160.aus.stglabs.ibm.com:8080/gerrit/23523
Tested-by: Jenkins Server
Reviewed-by: Craig C. Hamilton <cchamilt@us.ibm.com>
Reviewed-by: Andre A. Marin <aamarin@us.ibm.com>
Reviewed-by: Jennifer A. Stofer <stofer@us.ibm.com>
Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/22763
Tested-by: FSP CI Jenkins
Reviewed-by: Daniel M. Crowell <dcrowell@us.ibm.com>
Diffstat (limited to 'src')
5 files changed, 83 insertions, 31 deletions
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/ccs/ccs.C b/src/import/chips/p9/procedures/hwp/memory/lib/ccs/ccs.C index c305a7f93..4ae2aa684 100644 --- a/src/import/chips/p9/procedures/hwp/memory/lib/ccs/ccs.C +++ b/src/import/chips/p9/procedures/hwp/memory/lib/ccs/ccs.C @@ -7,7 +7,7 @@ /* */ /* EKB Project */ /* */ -/* COPYRIGHT 2015 */ +/* COPYRIGHT 2015,2016 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -116,7 +116,8 @@ fapi2::ReturnCode execute_inst_array(const fapi2::Target<TARGET_TYPE_MCBIST>& i_ FAPI_DBG("ccs statq 0x%llx, remaining: %d", stat_reg, poll_remaining); status = stat_reg; return status.getBit<TT::CCS_IN_PROGRESS>() != 1; - }); + }, + i_program.iv_probes); // Check for done and success. DONE being the only bit set. if (status == STAT_QUERY_SUCCESS) @@ -135,8 +136,6 @@ fapi_try_exit: /// /// @brief Execute a set of CCS instructions -/// @tparam T, the fapi2::TargetType - derived -/// @tparam TT, the ccsTraits associated with T - derived /// @param[in] the target to effect /// @param[in] the vector of instructions /// @param[in] the vector of ports diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/ccs/ccs.H b/src/import/chips/p9/procedures/hwp/memory/lib/ccs/ccs.H index 315d0a772..5eb16856d 100644 --- a/src/import/chips/p9/procedures/hwp/memory/lib/ccs/ccs.H +++ b/src/import/chips/p9/procedures/hwp/memory/lib/ccs/ccs.H @@ -7,7 +7,7 @@ /* */ /* EKB Project */ /* */ -/* COPYRIGHT 2015 */ +/* COPYRIGHT 2015,2016 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -277,8 +277,9 @@ class instruction_t /// @brief A class representing a series of CCS instructions, and the /// CCS engine parameters associated with running the instructions /// @tparam fapi2::TargetType T representing the fapi2 target which +/// @tparam fapi2::TargetType P representing the port /// contains the CCS engine (e.g., fapi2::TARGET_TYPE_MCBIST) -template< fapi2::TargetType T > +template< fapi2::TargetType T, fapi2::TargetType P = fapi2::TARGET_TYPE_MCA > class program { public: @@ -290,6 +291,9 @@ class program // Vector of instructions std::vector< instruction_t<T> > iv_instructions; poll_parameters iv_poll; + + // Vector of polling probes + std::vector< poll_probe<P> > iv_probes; }; /// @@ -583,6 +587,7 @@ inline fapi2::ReturnCode write_mode( const fapi2::Target<T>& i_target, const fap /// /// @brief Execute a set of CCS instructions - multiple ports /// @tparam T, the fapi2::TargetType - derived +/// @tparam P, the fapi2::TargetType of the ports - derived /// @tparam TT, the ccsTraits associated with T - derived /// @param[in] the target to effect /// @param[in] the vector of instructions @@ -592,11 +597,12 @@ inline fapi2::ReturnCode write_mode( const fapi2::Target<T>& i_target, const fap template< fapi2::TargetType T, fapi2::TargetType P, typename TT = ccsTraits<T> > fapi2::ReturnCode execute( const fapi2::Target<T>& i_target, ccs::program<T>& i_program, - const std::vector< fapi2::Target<P> >& i_ports ); + const std::vector< fapi2::Target<P> >& i_ports); /// /// @brief Execute a set of CCS instructions - single port /// @tparam T, the fapi2::TargetType - derived +/// @tparam P, the fapi2::TargetType of the ports - derived /// @tparam TT, the ccsTraits associated with T - derived /// @param[in] the target to effect /// @param[in] the vector of instructions @@ -606,7 +612,7 @@ fapi2::ReturnCode execute( const fapi2::Target<T>& i_target, template< fapi2::TargetType T, fapi2::TargetType P, typename TT = ccsTraits<T> > fapi2::ReturnCode execute( const fapi2::Target<T>& i_target, ccs::program<T>& i_program, - const fapi2::Target<P>& i_port ) + const fapi2::Target<P>& i_port) { // Mmm. Might want to find a better way to do this - seems expensive. BRS std::vector< fapi2::Target<P> > l_ports{ i_port }; diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/phy/cal_timers.H b/src/import/chips/p9/procedures/hwp/memory/lib/phy/cal_timers.H index 4045ada50..10fb29c10 100644 --- a/src/import/chips/p9/procedures/hwp/memory/lib/phy/cal_timers.H +++ b/src/import/chips/p9/procedures/hwp/memory/lib/phy/cal_timers.H @@ -7,7 +7,7 @@ /* */ /* EKB Project */ /* */ -/* COPYRIGHT 2015 */ +/* COPYRIGHT 2015,2016 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -54,7 +54,8 @@ uint64_t wr_lvl_cycles(const fapi2::Target<T>& i_target ) const uint64_t l_wr_lvl_cycles = (80 + TWLO_TWLOE) * WR_LVL_NUM_VALID_SAMPLES * (384 / (WR_LVL_BIG_STEP + 1) + (2 * (WR_LVL_BIG_STEP + 1)) / (WR_LVL_SMALL_STEP + 1)) + 20; - FAPI_DBG("wr_lvl_cycles: %d(%dns) (%d, %d, %d, %d)", l_wr_lvl_cycles, mss::cycles_to_ns(i_target, l_wr_lvl_cycles), + FAPI_DBG("wr_lvl_cycles: %llu(%lluns) (%llu, %llu, %llu, %llu)", l_wr_lvl_cycles, mss::cycles_to_ns(i_target, + l_wr_lvl_cycles), TWLO_TWLOE, WR_LVL_NUM_VALID_SAMPLES, WR_LVL_BIG_STEP, WR_LVL_SMALL_STEP); return l_wr_lvl_cycles; @@ -72,7 +73,7 @@ uint64_t dqs_align_cycles(const fapi2::Target<T>& i_target ) // This step runs for approximately 6 x 600 x 4 DRAM clocks per rank pair. const uint64_t l_dqs_align_cycles = 6 * 600 * 4; - FAPI_DBG("dqs_align_cycles: %d(%dns)", l_dqs_align_cycles, mss::cycles_to_ns(i_target, l_dqs_align_cycles)); + FAPI_DBG("dqs_align_cycles: %llu(%lluns)", l_dqs_align_cycles, mss::cycles_to_ns(i_target, l_dqs_align_cycles)); return l_dqs_align_cycles; } @@ -88,7 +89,7 @@ uint64_t rdclk_align_cycles(const fapi2::Target<T>& i_target ) // This step runs for approximately 24 x ((1024/COARSE_CAL_STEP_SIZE + 4 x COARSE_CAL_STEP_SIZE) x 4 + 32) DRAM // clocks per rank pair const uint64_t l_rdclk_align_cycles = 24 * ((1024 / COARSE_CAL_STEP_SIZE + 4 * COARSE_CAL_STEP_SIZE) * 4 + 32); - FAPI_DBG("rdclk_align_cycles: %d(%dns) (%d)", l_rdclk_align_cycles, + FAPI_DBG("rdclk_align_cycles: %llu(%lluns) (%llu)", l_rdclk_align_cycles, mss::cycles_to_ns(i_target, l_rdclk_align_cycles), COARSE_CAL_STEP_SIZE); return l_rdclk_align_cycles; } @@ -106,7 +107,7 @@ uint64_t read_ctr_cycles(const fapi2::Target<T>& i_target ) // 4 x CONSEQ_PASS)) x 24 DRAM clocks per rank pair. const uint64_t l_read_ctr_cycles = 6 * (512 / COARSE_CAL_STEP_SIZE + 4 * (COARSE_CAL_STEP_SIZE + 4 * CONSEQ_PASS)) * 24; - FAPI_DBG("read_ctr_cycles %d(%dns) (%d, %d)", l_read_ctr_cycles, mss::cycles_to_ns(i_target, l_read_ctr_cycles), + FAPI_DBG("read_ctr_cycles %llu(%lluns) (%llu, %llu)", l_read_ctr_cycles, mss::cycles_to_ns(i_target, l_read_ctr_cycles), COARSE_CAL_STEP_SIZE, CONSEQ_PASS); return l_read_ctr_cycles; } @@ -123,11 +124,11 @@ uint64_t write_ctr_cycles(const fapi2::Target<T>& i_target ) // 1000 + (NUM_VALID_SAMPLES * (FW_WR_RD + FW_RD_WR + 16) * // (1024/(SMALL_STEP +1) + 128/(BIG_STEP +1)) + 2 * (BIG_STEP+1)/(SMALL_STEP+1)) x 24 DRAM // clocks per rank pair. - const uint64_t l_write_ctr_cycles = 1000 + (WR_LVL_NUM_VALID_SAMPLES * (WR_CNTR_FW_WR_RD + WR_CNTR_FW_RD_WR + 16) * - (1024 / (WR_LVL_SMALL_STEP + 1) + 128 / (WR_LVL_BIG_STEP + 1)) + 2 * - (WR_LVL_BIG_STEP + 1) / (WR_LVL_SMALL_STEP + 1)) * 24; + uint64_t l_write_ctr_cycles = 1000 + (WR_LVL_NUM_VALID_SAMPLES * (WR_CNTR_FW_WR_RD + WR_CNTR_FW_RD_WR + 16) * + (1024 / (WR_LVL_SMALL_STEP + 1) + 128 / (WR_LVL_BIG_STEP + 1)) + 2 * + (WR_LVL_BIG_STEP + 1) / (WR_LVL_SMALL_STEP + 1)) * 24; - FAPI_DBG("write_ctr_cycles: %d(%dns) (%d, %d, %d, %d, %d)", + FAPI_DBG("write_ctr_cycles: %lu(%luns) (%u, %u, %u, %u, %u)", l_write_ctr_cycles, mss::cycles_to_ns(i_target, l_write_ctr_cycles), WR_LVL_NUM_VALID_SAMPLES, WR_CNTR_FW_WR_RD, WR_CNTR_FW_RD_WR, WR_LVL_BIG_STEP, WR_LVL_SMALL_STEP); @@ -146,7 +147,7 @@ uint64_t coarse_wr_cycles(const fapi2::Target<T>& i_target ) // The run length given here is the maximum run length for this calibration algorithm. // This step runs for approximately 40 DRAM clocks per rank pair. static const uint64_t l_coarse_wr_cycles = 40; - FAPI_DBG("coarse_wr_cycles: %d(%dns)", l_coarse_wr_cycles, mss::cycles_to_ns(i_target, l_coarse_wr_cycles)); + FAPI_DBG("coarse_wr_cycles: %llu(%lluns)", l_coarse_wr_cycles, mss::cycles_to_ns(i_target, l_coarse_wr_cycles)); return l_coarse_wr_cycles; } @@ -162,7 +163,7 @@ uint64_t coarse_rd_cycles(const fapi2::Target<T>& i_target ) // The run length given here is the maximum run length for this calibration algorithm. // This step runs for approximately 32 DRAM clocks per rank pair. static const uint64_t l_coarse_rd_cycles = 32; - FAPI_DBG("coarse_rd_cycles: %d(%dns)", l_coarse_rd_cycles, mss::cycles_to_ns(i_target, l_coarse_rd_cycles)); + FAPI_DBG("coarse_rd_cycles: %llu(%lluns)", l_coarse_rd_cycles, mss::cycles_to_ns(i_target, l_coarse_rd_cycles)); return l_coarse_rd_cycles; } @@ -203,11 +204,13 @@ inline fapi2::ReturnCode cal_timer_setup(const fapi2::Target<T>& i_target, i_poll.iv_delay = DELAY_1US; i_poll.iv_sim_delay = mss::cycles_to_simcycles(mss::ns_to_cycles(i_target, DELAY_1US)); - i_poll.iv_poll_count = (mss::cycles_to_ns(i_target, l_total_cycles) - i_poll.iv_initial_delay) / i_poll.iv_delay; + // Round up to the cycles left after the initial delay + uint64_t l_ns_left = mss::cycles_to_ns(i_target, l_total_cycles) - i_poll.iv_initial_delay; + i_poll.iv_poll_count = l_ns_left / i_poll.iv_delay; + i_poll.iv_poll_count += l_ns_left % i_poll.iv_delay ? 0 : 1; // Don't let the poll count be 0 - that just makes for a bad day. i_poll.iv_poll_count = (i_poll.iv_poll_count == 0) ? 1 : i_poll.iv_poll_count; - #else if (CAL_ABORT_ON_ERROR) @@ -221,7 +224,10 @@ inline fapi2::ReturnCode cal_timer_setup(const fapi2::Target<T>& i_target, i_poll.iv_delay = DELAY_1US; i_poll.iv_sim_delay = mss::cycles_to_simcycles(mss::ns_to_cycles(i_target, DELAY_1US)); - i_poll.iv_poll_count = (mss::cycles_to_ns(i_target, l_total_cycles) - i_poll.iv_initial_delay) / i_poll.iv_delay; + // Round up to the cycles left after the initial delay + uint64_t l_ns_left = mss::cycles_to_ns(i_target, l_total_cycles) - i_poll.iv_initial_delay; + i_poll.iv_poll_count = l_ns_left / i_poll.iv_delay; + i_poll.iv_poll_count += l_ns_left % i_poll.iv_delay ? 0 : 1; // Don't let the poll count be 0 - that just makes for a bad day. i_poll.iv_poll_count = (i_poll.iv_poll_count == 0) ? 1 : i_poll.iv_poll_count; @@ -234,7 +240,7 @@ inline fapi2::ReturnCode cal_timer_setup(const fapi2::Target<T>& i_target, #endif - FAPI_DBG("cal abort on error? %s. tc: %dc, id: %dns(%dsc), d: %d(%dsc), pc: %d", + FAPI_DBG("cal abort on error? %s. tc: %lluc, id: %lluns(%llusc), d: %llu(%llusc), pc: %llu", (CAL_ABORT_ON_ERROR ? "yup" : "nope"), l_total_cycles, i_poll.iv_initial_delay, i_poll.iv_initial_sim_delay, i_poll.iv_delay, i_poll.iv_sim_delay, i_poll.iv_poll_count); diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/utils/conversions.H b/src/import/chips/p9/procedures/hwp/memory/lib/utils/conversions.H index 3989c172b..d637daf17 100644 --- a/src/import/chips/p9/procedures/hwp/memory/lib/utils/conversions.H +++ b/src/import/chips/p9/procedures/hwp/memory/lib/utils/conversions.H @@ -7,7 +7,7 @@ /* */ /* EKB Project */ /* */ -/* COPYRIGHT 2015 */ +/* COPYRIGHT 2015,2016 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -108,7 +108,7 @@ inline uint64_t ps_to_cycles(const fapi2::Target<T>& i_target, const uint64_t i_ l_remainder = i_ps % l_divisor; // Make sure we add a cycle if there wasn't an even number of cycles in the input - FAPI_DBG("converting %dps to %d cycles", i_ps, l_quotient + (l_remainder == 0 ? 0 : 1)); + FAPI_DBG("converting %llups to %llu cycles", i_ps, l_quotient + (l_remainder == 0 ? 0 : 1)); return l_quotient + (l_remainder == 0 ? 0 : 1); @@ -136,7 +136,7 @@ inline uint64_t cycles_to_ps(const fapi2::Target<T>& i_target, const uint64_t i_ FAPI_TRY( mss::freq( find_target<fapi2::TARGET_TYPE_MCBIST>(i_target), l_freq) ); - FAPI_DBG("converting %d cycles to %dps", i_cycles, i_cycles * mhz_to_ps(l_freq)); + FAPI_DBG("converting %llu cycles to %llups", i_cycles, i_cycles * mhz_to_ps(l_freq)); return i_cycles * mhz_to_ps(l_freq); fapi_try_exit: @@ -203,7 +203,7 @@ template< fapi2::TargetType T > inline uint64_t cycles_to_ns(const fapi2::Target<T>& i_target, const uint64_t i_cycles) { uint64_t l_ns = cycles_to_time<T, CONVERT_PS_IN_A_NS>(i_target, i_cycles); - FAPI_DBG("converting %d cycles to %dns", i_cycles, l_ns); + FAPI_DBG("converting %llu cycles to %lluns", i_cycles, l_ns); return l_ns; } @@ -218,7 +218,7 @@ template< fapi2::TargetType T > inline uint64_t cycles_to_us(const fapi2::Target<T>& i_target, const uint64_t i_cycles) { uint64_t l_us = cycles_to_time<T, CONVERT_PS_IN_A_US>(i_target, i_cycles); - FAPI_DBG("converting %d cycles to %dus", i_cycles, l_us); + FAPI_DBG("converting %llu cycles to %lluus", i_cycles, l_us); return l_us; } diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/utils/poll.H b/src/import/chips/p9/procedures/hwp/memory/lib/utils/poll.H index 462e251f4..a1c03a692 100644 --- a/src/import/chips/p9/procedures/hwp/memory/lib/utils/poll.H +++ b/src/import/chips/p9/procedures/hwp/memory/lib/utils/poll.H @@ -7,7 +7,7 @@ /* */ /* EKB Project */ /* */ -/* COPYRIGHT 2015 */ +/* COPYRIGHT 2015,2016 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -39,10 +39,40 @@ namespace mss { /// +/// @class poll_probe +/// @brief Structure to represent a vector of addresses to probe during the polling loop +/// @tparam fapi2::TargetType, representing the target of the probe (does a getscom) +/// +template< fapi2::TargetType T > +struct poll_probe +{ + /// + /// @brief poll-probe constructor + /// @param[in] i_target, the target for the scom operation + /// @param[in] i_tag, some useful text to output with the register data + /// @param[in] i_register, the register for the scom operation + /// + poll_probe( const fapi2::Target<T>& i_target, const char* i_tag, const uint64_t i_register ): + iv_target(i_target), + iv_tag(i_tag), + iv_register(i_register) + { + } + + fapi2::Target<T> iv_target; + + // String to be output with the value of the register, + // Often is the name of the register + const char* iv_tag; + uint64_t iv_register; +}; + +/// /// @brief Poll paramter data structure. /// Represents the parameters used to poll a register. /// _delays are in ns, _sim_delays are in sim_cycles /// See conversions.H for conversions. +/// struct poll_parameters { // We need to decide how long to wait before pounding the compeletion SCOM. @@ -81,6 +111,7 @@ struct poll_parameters /// @brief Poll a scom, return whether the poll croteria were met or not /// @tparam T, the fapi2::TargetType /// @tparam L, a lambda representing the completion criteria - returns true +/// @tparam P, the fapi2::TargetType of the target in the probe vector /// iff the poll criteria have been met (and the polling can stop) /// @param[in] i_target, target for the getScom /// @param[in] i_addr, the address for the scom @@ -90,15 +121,17 @@ struct poll_parameters /// { /// return true; /// } +/// @param[in] i_probes, a vector of poll_probes to be used in the polling loop (optional) /// @return bool, true iff poll criteria was met before the number of iterations /// ran out. /// @warning If you want to handle a failure as an error, you need to wrap /// the call to poll() in a FAPI_ASSERT. FAPI_TRY is *not* the right mechanism /// as poll() does not return a fapi2::ReturnCode /// -template< fapi2::TargetType T, typename L > +template< fapi2::TargetType T, typename L, fapi2::TargetType P = fapi2::TARGET_TYPE_MCA > inline bool poll(const fapi2::Target<T>& i_target, const uint64_t i_addr, - const poll_parameters i_params, L i_fn) + const poll_parameters i_params, L i_fn, + const std::vector< poll_probe<P> >& i_probes = std::vector< poll_probe<P> >() ) { fapi2::buffer<uint64_t> l_reg; @@ -111,6 +144,14 @@ inline bool poll(const fapi2::Target<T>& i_target, const uint64_t i_addr, for ( size_t l_poll_limit = i_params.iv_poll_count; l_poll_limit > 0; --l_poll_limit ) { + // Output anything in the probes + for (auto p : i_probes) + { + fapi2::buffer<uint64_t> l_data; + FAPI_TRY( mss::getScom(p.iv_target, p.iv_register, l_data) ); + FAPI_INF("%s: %s 0x%016llx 0x%016llx", mss::c_str(p.iv_target), p.iv_tag, p.iv_register, l_data); + } + FAPI_TRY( mss::getScom(i_target, i_addr, l_reg) ); if (i_fn(l_poll_limit, l_reg) == true) |