summaryrefslogtreecommitdiffstats
path: root/src/import/chips/p9/procedures/hwp/memory/lib/mcbist/sim.C
diff options
context:
space:
mode:
Diffstat (limited to 'src/import/chips/p9/procedures/hwp/memory/lib/mcbist/sim.C')
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/mcbist/sim.C160
1 files changed, 160 insertions, 0 deletions
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/mcbist/sim.C b/src/import/chips/p9/procedures/hwp/memory/lib/mcbist/sim.C
new file mode 100644
index 000000000..029072fe9
--- /dev/null
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/mcbist/sim.C
@@ -0,0 +1,160 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: chips/p9/procedures/hwp/memory/lib/mcbist/sim.C $ */
+/* */
+/* IBM CONFIDENTIAL */
+/* */
+/* EKB Project */
+/* */
+/* COPYRIGHT 2016 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* The source code for this program is not published or otherwise */
+/* divested of its trade secrets, irrespective of what has been */
+/* deposited with the U.S. Copyright Office. */
+/* */
+/* IBM_PROLOG_END_TAG */
+
+///
+/// @file mcbist/sim.C
+/// @brief MCBIST/memdiags functions for when we're in simulation mode
+///
+// *HWP HWP Owner: Brian Silver <bsilver@us.ibm.com>
+// *HWP HWP Backup: Andre Marin <aamarin@us.ibm.com>
+// *HWP Team: Memory
+// *HWP Level: 2
+// *HWP Consumed by: FSP:HB
+
+#include <fapi2.H>
+
+#include <lib/dimm/rank.H>
+#include <lib/mcbist/address.H>
+#include <lib/mcbist/mcbist.H>
+#include <lib/mcbist/patterns.H>
+#include <lib/mcbist/sim.H>
+
+using fapi2::TARGET_TYPE_MCBIST;
+using fapi2::TARGET_TYPE_MCA;
+using fapi2::TARGET_TYPE_SYSTEM;
+using fapi2::FAPI2_RC_SUCCESS;
+
+namespace mss
+{
+
+namespace mcbist
+{
+
+namespace sim
+{
+
+///
+/// @brief Perform a sim version of initializing memory
+/// @param[in] i_target MCBIST
+/// @param[in] i_pattern an index representing a pattern to use to initize memory (defaults to 0)
+/// @return FAPI2_RC_SUCCESS iff ok
+///
+template<>
+fapi2::ReturnCode sf_init( const fapi2::Target<TARGET_TYPE_MCBIST>& i_target,
+ const uint64_t i_pattern )
+{
+ FAPI_INF("Start sim init");
+
+ // If we're running in the simulator, we want to only touch the addresses which training touched
+
+ for (const auto& p : i_target.getChildren<TARGET_TYPE_MCA>())
+ {
+ std::vector<uint64_t> l_pr;
+ mss::mcbist::program<TARGET_TYPE_MCBIST> l_program;
+
+ mss::mcbist::address l_start;
+ mss::mcbist::address l_end;
+
+ size_t l_rank_address_pair = 0;
+
+ // In sim we know a few things ...
+ // Get the primary ranks for this port. We know there can only be 4, and we know we only trained the primary
+ // ranks. Therefore, we only need to clean up the primary ranks. And because there's 4 max, we can do it
+ // all using the 4 address range registers of tne MCBIST (broadcast currently not considered.)
+ // So we can write 0's to those to get their ECC fixed up.
+ FAPI_TRY( mss::primary_ranks(p, l_pr) );
+ fapi2::Assert( l_pr.size() <= mss::MAX_RANK_PER_DIMM );
+
+ for (auto r = l_pr.begin(); r != l_pr.end(); ++l_rank_address_pair, ++r)
+ {
+ FAPI_INF("sim init %s, rank %d", mss::c_str(p), *r);
+
+ // Setup l_start to represent this rank, and then make the end address from that.
+ l_start.set_master_rank(*r);
+
+ l_start.get_range<mss::mcbist::address::COL>(l_end);
+ // Set C3 bit to get an entire cache line
+ l_end.set_field<mss::mcbist::address::COL>(0b1000000);
+
+ // By default we're in maint address mode, not address counting mode. So we give it a start and end, and ignore
+ // anything invalid - that's what maint address mode is all about
+ mss::mcbist::config_address_range(i_target, l_start, l_end, l_rank_address_pair);
+
+ // Write
+ {
+ // Run in ECC mode, 64B writes (superfast mode)
+
+ mss::mcbist::subtest_t<TARGET_TYPE_MCBIST> l_fw_subtest =
+ mss::mcbist::write_subtest<TARGET_TYPE_MCBIST>();
+
+ l_fw_subtest.enable_port(mss::relative_pos<TARGET_TYPE_MCBIST>(p));
+ l_fw_subtest.change_addr_sel(l_rank_address_pair);
+ l_fw_subtest.enable_dimm(mss::get_dimm_from_rank(*r));
+ l_program.iv_subtests.push_back(l_fw_subtest);
+ FAPI_DBG("adding superfast write for %s rank %d (dimm %d)", mss::c_str(p), *r, mss::get_dimm_from_rank(*r));
+ }
+
+ // Read - we do a read here as verification can use this as a tool as we do the write and then the read.
+ // If we failed to write properly the read would thow ECC errors. Just a write (which the real hardware would
+ // do) doesn't catch that. This takes longer, but it's not terribly long in any event.
+ {
+ // Run in ECC mode, 64B writes (superfast mode)
+ mss::mcbist::subtest_t<TARGET_TYPE_MCBIST> l_fr_subtest =
+ mss::mcbist::read_subtest<TARGET_TYPE_MCBIST>();
+
+ l_fr_subtest.enable_port(mss::relative_pos<TARGET_TYPE_MCBIST>(p));
+ l_fr_subtest.change_addr_sel(l_rank_address_pair);
+ l_fr_subtest.enable_dimm(mss::get_dimm_from_rank(*r));
+ l_program.iv_subtests.push_back(l_fr_subtest);
+ FAPI_DBG("adding superfast read for %s rank %d (dimm %d)", mss::c_str(p), *r, mss::get_dimm_from_rank(*r));
+ }
+ }
+
+ // Write pattern
+ FAPI_TRY( mss::mcbist::load_pattern(i_target, i_pattern) );
+
+ // Setup the sim polling based on a heuristic <cough>guess</cough>
+ // Looks like ~400ck per address for a write/read program on the sim-dimm, and add a long number of polls
+ // On real hardware wait 100ms and then start polling for another 5s
+ l_program.iv_poll.iv_initial_sim_delay = mss::cycles_to_simcycles(((l_end - l_start) * l_pr.size()) * 800);
+ l_program.iv_poll.iv_initial_delay = 100 * mss::DELAY_1MS;
+ l_program.iv_poll.iv_sim_delay = 100000;
+ l_program.iv_poll.iv_delay = 10 * mss::DELAY_1MS;
+ l_program.iv_poll.iv_poll_count = 500;
+
+ // Just one port for now. Per Shelton we need to set this in maint address mode
+ // even tho we specify the port/dimm in the subtest.
+ fapi2::buffer<uint8_t> l_port;
+ l_port.setBit(mss::relative_pos<TARGET_TYPE_MCBIST>(p));
+ l_program.select_ports(l_port >> 4);
+
+ // Kick it off, wait for a result
+ FAPI_TRY( mss::mcbist::execute(i_target, l_program) );
+ }
+
+fapi_try_exit:
+ FAPI_INF("End sim init");
+ return fapi2::current_err;
+}
+
+} // namespace sim
+
+} // namespace mcbist
+
+} // namespace mss
OpenPOWER on IntegriCloud