summaryrefslogtreecommitdiffstats
path: root/src/import/chips/p9/procedures
diff options
context:
space:
mode:
authorBrian Silver <bsilver@us.ibm.com>2016-01-22 06:22:02 -0600
committerDaniel M. Crowell <dcrowell@us.ibm.com>2016-04-01 21:22:34 -0400
commit54fa8bf62ae4e8ccdac831b792cd2e8951bf32b3 (patch)
treecf98d9f666780ebf0ff3794c3d069be952ac020b /src/import/chips/p9/procedures
parent552bf3a724e5e4358c8bc340f08ffdc8e8625082 (diff)
downloadtalos-hostboot-54fa8bf62ae4e8ccdac831b792cd2e8951bf32b3.tar.gz
talos-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/import/chips/p9/procedures')
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/ccs/ccs.C7
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/ccs/ccs.H14
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/phy/cal_timers.H36
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/utils/conversions.H10
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/utils/poll.H47
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)
OpenPOWER on IntegriCloud